home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / turbovis / ned103.zip / NEWEDIT.PAS < prev    next >
Pascal/Delphi Source File  |  1992-08-28  |  160KB  |  6,136 lines

  1. { FILE:  newedit.pas }
  2.  
  3.  
  4.  
  5. unit NewEdit;
  6.  
  7.  
  8.  
  9. { ******************************************************************** }
  10. {                                                                      }
  11. { NOTICE:  The following code was written by Borland International.    }
  12. {          The code is for use by TP6.0 users.  Keep the copyright     }
  13. {          notice intact!                                              }
  14. {                                                                      }
  15. {          Turbo Pascal 6.0                                            }
  16. {          Turbo Vision Demo                                           }
  17. {          Copyright (c) 1990 by Borland International                 }
  18. {                                                                      }
  19. {          I have taken the liberty of prettying up the source.        }
  20. {          I have also taken the liberty of adding additional features.}
  21. {          Search for the following keywords and compare your original }
  22. {          editors code to any code between the Start/Stop comments    }
  23. {          for changes.                                                }
  24. {                                                                      }
  25. { Label    Description:                                                }
  26. { ------   ------------                                                }
  27. {                                                                      }
  28. { CENTER - Added a feature to center text on a line.                   }
  29. {          Centering only works to Right_Margin.                       }
  30. {                                                                      }
  31. { CTRLBK - Added new key to map to ^QH.  Does the same thing.          }
  32. {                                                                      }
  33. { HOMEND - Added feature to move cursor to top and bottom of page      }
  34. {          using the [Ctrl]-[Home] and [Ctrl]-[End] keys.              }
  35. {                                                                      }
  36. { LOAD   - Fixed bug that prevented load operations and added new      }
  37. {          stream reads to handle new TEditor objects.                 }
  38. {                                                                      }
  39. { MARK   - A place mark type feature.  Exactly the same as WordStar's  }
  40. {          ^K# and ^Q#, except that the mark is for the exact poistion }
  41. {          the cursor is at in a line, not just the start of a line.   }
  42. {                                                                      }
  43. { INDENT - Change AutoIndent from a ^O to a ^QI call.                  }
  44. {                                                                      }
  45. { INSLIN - Insert new line at cursor and maintain cursor position.     }
  46. {                                                                      }
  47. { JLINE  - A jump to line number feature.  Pressing ^JL will bring     }
  48. {          up a dialog box asking the line number to jump to.          }
  49. {                                                                      }
  50. { PRETAB - Preset tab feature.  Tabs are preset in increments of 7.    }
  51. {          The user can call up a dialog and set the tabs in any way   }
  52. {          they want.  Uses WordStar ^OI feature.  Note that a "real"  }
  53. {          tab (^I) is no longer supported.  Tabs are converted to     }
  54. {          spaces if you are inserting text, and only move the cursor  }
  55. {          to the next tab stop if you are overwriting text.           }
  56. {                                                                      }
  57. { REFDOC - Reformats a document from either the beginning or the       }
  58. {          current line the cursor is on.                              }
  59. {                                                                      }
  60. { REFORM - Reformats a paragraph to the Right_Margin setting.          }
  61. {          This feature works regardless if wordwrap is active,        }
  62. {          as a standalone ^B call.                                    }
  63. {                                                                      }
  64. { RMSET  - User can set the Right_Margin by pressing ^OR.  A dialog    }
  65. {          box comes up asking you for the Right_Margin you want.      }
  66. {          The dialog box has the current Right_Margin displayed in    }
  67. {          it.  There is only one dialog button "cmOK."  Selecting     }
  68. {          this button, or aborting, will maintain the current margin. }
  69. {          Default Right_Margin is 76.  Valid entries are >10 or < 256.}
  70. {                                                                      }
  71. { SAVE   - Add new save options.  Keep F2 as the default cmSave to     }
  72. {          save file and continue editing, but tie ^KS to it also.     }
  73. {          Add ^KT to cmSaveAs to save current file to another file.   }
  74. {          Add ^KD and ^KX as cmSaveDone to do an immediate save and   }
  75. {          automatically remove the editor from the desktop.           }
  76. {                                                                      }
  77. { SCRLBG - Added a bug fix so editor doesn't consume ScrollbarChanged  }
  78. {          events.                                                     }
  79. {                                                                      }
  80. { SCRLDN - Added feature to scroll the screen up a line-at-a-time      }
  81. {          by pressing ^Z.                                             }
  82. {                                                                      }
  83. { SCRLUP - Added feature to scroll the screen down a line-at-a-time    }
  84. {          by pressing ^W.                                             }
  85. {                                                                      }
  86. { SELDEL - Disallowed editor default of arbitrarily deleting selected  }
  87. {          text when any key is pressed.  You now use the [Del] key.   }
  88. {                                                                      }
  89. { SELWRD - Added feature to select a word only by pressing ^KT.        }
  90. {                                                                      }
  91. { STATS  - Changed the appearance of the PIndicator line.              }
  92. {          It now shows "M" for modified, "I" for AutoIndent,          }
  93. {          and "W" for wordwrap.                                       }
  94. {                                                                      }
  95. { STORE  - Fixed bug that prevented store operations and added new     }
  96. {          stream writes to handle new TEditor objects.  Send thanks   }
  97. {          to Johnathan Stein CIS: 76576,470 in the form of a lollipop }
  98. {          for finding this bug.                                       }
  99. {                                                                      }
  100. { UNDO   - Added IDE ^QL undo feature.  ^U is still functional.        }
  101. {                                                                      }
  102. { WRAP   - A word wrap modification.  Allows user to toggle wordwrap   }
  103. {          on or off.  If on, wordwrap will occur when the cursor      }
  104. {          reaches +1 of the current Right_Margin setting.  Wrap works }
  105. {          as a "push the line out until cursor gets to Right_Margin"  }
  106. {          principle.  Wordwrap also supports the AutoIndent feature.  }
  107. {                                                                      }
  108. { Al Andersen - 02/29/92.                                              }
  109. {                                                                      }
  110. { ******************************************************************** }
  111.  
  112.  
  113. {$F+,I-,O+,S-,V-,X+,D-}
  114.  
  115.  
  116.  
  117. interface
  118.  
  119. uses Drivers,
  120.      Objects,
  121.      Views;
  122.  
  123.  
  124.  
  125. CONST { Command constants for saving files and finding text. }
  126.  
  127.   cmSave        = 80;
  128.   cmSaveAs      = 81;
  129.   cmFind        = 82;
  130.   cmReplace     = 83;
  131.   cmSearchAgain = 84;
  132.  
  133.   { SAVE - Start. }
  134.  
  135.   cmSaveDone    = 85;
  136.  
  137.   { SAVE - Stop.  }
  138.  
  139.  
  140.  
  141. CONST { New editor commands that user may want to put into a menu. }
  142.  
  143.   { CENTER - Start. }
  144.   { HOMEND - Start. }
  145.   { INSLIN - Start. }
  146.   { JLINE  - Start. }
  147.   { MARK   - Start. }
  148.   { PRETAB - Start. }
  149.   { REFDOC - Start. }
  150.   { REFORM - Start. }
  151.   { RMSET  - Start. }
  152.   { SCRLDN - Start. }
  153.   { SCRLDN - Start. }
  154.   { SELWRD - Start. }
  155.   { WRAP   - Start. }
  156.  
  157.   cmCenterText  = 200;
  158.   cmEndPage     = 201;
  159.   cmHomePage    = 202;
  160.   cmIndentMode  = 203;
  161.   cmInsertLine  = 204;
  162.   cmJumpLine    = 205;
  163.   cmJumpMark0   = 206;
  164.   cmJumpMark1   = 207;
  165.   cmJumpMark2   = 208;
  166.   cmJumpMark3   = 209;
  167.   cmJumpMark4   = 210;
  168.   cmJumpMark5   = 211;
  169.   cmJumpMark6   = 212;
  170.   cmJumpMark7   = 213;
  171.   cmJumpMark8   = 214;
  172.   cmJumpMark9   = 215;
  173.   cmReformDoc   = 216;
  174.   cmReformPara  = 217;
  175.   cmRightMargin = 218;
  176.   cmScrollDown  = 219;
  177.   cmScrollUp    = 220;
  178.   cmSelectWord  = 221;
  179.   cmSetMark0    = 222;
  180.   cmSetMark1    = 223;
  181.   cmSetMark2    = 224;
  182.   cmSetMark3    = 225;
  183.   cmSetMark4    = 226;
  184.   cmSetMark5    = 227;
  185.   cmSetMark6    = 228;
  186.   cmSetMark7    = 229;
  187.   cmSetMark8    = 230;
  188.   cmSetMark9    = 231;
  189.   cmSetTabs     = 232;
  190.   cmTabKey      = 233;
  191.   cmWordWrap    = 234;
  192.  
  193.  
  194.   { WRAP   - Stop. }
  195.   { SELWRD - Stop. }
  196.   { SCRLUP - Stop. }
  197.   { SCRLDN - Stop. }
  198.   { RMSET  - Stop. }
  199.   { REFORM - Stop. }
  200.   { REFDOC - Stop. }
  201.   { PRETAB - Stop. }
  202.   { MARK   - Stop. }
  203.   { JLINE  - Stop. }
  204.   { INSLIN - Stop. }
  205.   { HOMEND - Stop. }
  206.   { CENTER - Stop. }
  207.  
  208.  
  209.  
  210. CONST { Command constants for cursor movement and modifying text. }
  211.  
  212.   cmCharLeft      = 500;
  213.   cmCharRight     = 501;
  214.   cmWordLeft      = 502;
  215.   cmWordRight     = 503;
  216.   cmLineStart     = 504;
  217.   cmLineEnd       = 505;
  218.   cmLineUp        = 506;
  219.   cmLineDown      = 507;
  220.   cmPageUp        = 508;
  221.   cmPageDown      = 509;
  222.   cmTextStart     = 510;
  223.   cmTextEnd       = 511;
  224.   cmNewLine       = 512;
  225.   cmBackSpace     = 513;
  226.   cmDelChar       = 514;
  227.   cmDelWord       = 515;
  228.   cmDelStart      = 516;
  229.   cmDelEnd        = 517;
  230.   cmDelLine       = 518;
  231.   cmInsMode       = 519;
  232.   cmStartSelect   = 520;
  233.   cmHideSelect    = 521;
  234.   cmUpdateTitle   = 523;
  235.  
  236.   { STATS - Start. }
  237.  
  238.   cmBludgeonStats = 524;
  239.  
  240.   { STATS - Stop. } { Needed this for TEditWindow.HandleEvent }
  241.  
  242.  
  243.  
  244. CONST { Editor constants for dialog boxes. }
  245.  
  246.   edOutOfMemory   = 0;
  247.   edReadError     = 1;
  248.   edWriteError    = 2;
  249.   edCreateError   = 3;
  250.   edSaveModify    = 4;
  251.   edSaveUntitled  = 5;
  252.   edSaveAs        = 6;
  253.   edFind          = 7;
  254.   edSearchFailed  = 8;
  255.   edReplace       = 9;
  256.   edReplacePrompt = 10;
  257.  
  258.   { JLINE  - Start. }
  259.   { PRETAB - Start. }
  260.   { REFDOC - Start. }
  261.   { RMSET  - Start. }
  262.   { WRAP   - Start. }
  263.  
  264.   edJumpToLine         = 11;
  265.   edPasteNotPossible   = 12;
  266.   edReformatDocument   = 13;
  267.   edReformatNotAllowed = 14;
  268.   edReformNotPossible  = 15;
  269.   edReplaceNotPossible = 16;
  270.   edRightMargin        = 17;
  271.   edSetTabStops        = 18;
  272.   edWrapNotPossible    = 19;
  273.  
  274.   { WRAP   - Stop. }
  275.   { RMSET  - Stop. }
  276.   { REFDOC - Stop. }
  277.   { PRETAB - Stop. }
  278.   { JLINE  - Stop. }
  279.  
  280.  
  281.  
  282. CONST { Editor flag constants for dialog options. }
  283.  
  284.   efCaseSensitive   = $0001;
  285.   efWholeWordsOnly  = $0002;
  286.   efPromptOnReplace = $0004;
  287.   efReplaceAll      = $0008;
  288.   efDoReplace       = $0010;
  289.   efBackupFiles     = $0100;
  290.  
  291.  
  292.  
  293. CONST { Constants for object palettes. }
  294.  
  295.   CIndicator = #2#3;
  296.   CEditor    = #6#7;
  297.   CMemo      = #26#27;
  298.  
  299.  
  300.  
  301. CONST { Length constants. }
  302.  
  303.   MaxLineLength = 256;
  304.  
  305.   { PRETAB - Start. }
  306.  
  307.   Tab_Stop_Length = 74;
  308.  
  309.   { PRETAB - Stop. }
  310.  
  311.  
  312.  
  313. TYPE
  314.  
  315.   TEditorDialog = function (Dialog : Integer; Info : Pointer) : Word;
  316.  
  317.  
  318.  
  319. TYPE
  320.  
  321.   PIndicator = ^TIndicator;
  322.   TIndicator = object (TView)
  323.  
  324.     Location   : Objects.TPoint;
  325.     Modified   : Boolean;
  326.  
  327.     { STATS - Start. }
  328.  
  329.     AutoIndent   : Boolean;          { Added boolean for AutoIndent mode. }
  330.     WordWrap     : Boolean;          { Added boolean for WordWrap mode.   }
  331.  
  332.     { STATS - Stop. }
  333.  
  334.     constructor Init (var Bounds : TRect);
  335.     procedure   Draw; virtual;
  336.     function    GetPalette : Views.PPalette; virtual;
  337.     procedure   SetState (AState : Word; Enable : Boolean); virtual;
  338.  
  339.     { STATS - Start. }
  340.  
  341.     procedure   SetValue (ALocation : Objects.TPoint; IsAutoIndent : Boolean;
  342.                                                       IsModified   : Boolean;
  343.                                                       IsWordWrap   : Boolean);
  344.  
  345.     { STATS - Stop. } { Changed parameter calls to show them on TIndicator line. }
  346.  
  347.   end;
  348.  
  349.  
  350.  
  351. TYPE
  352.  
  353.   PEditBuffer = ^TEditBuffer;
  354.   TEditBuffer = array[0..65519] of Char;
  355.  
  356.  
  357.  
  358. TYPE
  359.  
  360.   PEditor = ^TEditor;
  361.   TEditor = object (TView)
  362.  
  363.     HScrollBar         : PScrollBar;
  364.     VScrollBar         : PScrollBar;
  365.     Indicator          : PIndicator;
  366.     Buffer             : PEditBuffer;
  367.     BufSize            : Word;
  368.     BufLen             : Word;
  369.     GapLen             : Word;
  370.     SelStart           : Word;
  371.     SelEnd             : Word;
  372.     CurPtr             : Word;
  373.     CurPos             : Objects.TPoint;
  374.     Delta              : Objects.TPoint;
  375.     Limit              : Objects.TPoint;
  376.     DrawLine           : Integer;
  377.     DrawPtr            : Word;
  378.     DelCount           : Word;
  379.     InsCount           : Word;
  380.     IsValid            : Boolean;
  381.     CanUndo            : Boolean;
  382.     Modified           : Boolean;
  383.     Selecting          : Boolean;
  384.     Overwrite          : Boolean;
  385.     AutoIndent         : Boolean;
  386.  
  387.     { WRAP - Start. }
  388.  
  389.     BlankLine          : Word;    { First blank line after a paragraph.      }
  390.     Word_Wrap          : Boolean; { Added boolean to toggle wordwrap on/off. }
  391.  
  392.     { WRAP - Stop. }
  393.  
  394.     { JLINE - Start. }
  395.  
  396.     Line_Number        : string [4]; { Holds line number to jump to. }
  397.  
  398.     { JLINE - Stop. }
  399.  
  400.     { RMSET - Start. }
  401.  
  402.     Right_Margin       : Integer; { Added integer to set right margin.       }
  403.  
  404.     { RMSET - Stop. }
  405.  
  406.     { PRETAB - Start. }
  407.  
  408.     Tab_Settings : String[Tab_Stop_Length]; { Added string to hold tab stops. }
  409.  
  410.     { PRETAB - Stop. }
  411.  
  412.     constructor Init (var Bounds : TRect; AHScrollBar, AVScrollBar : PScrollBar;
  413.                           AIndicator : PIndicator; ABufSize : Word);
  414.     constructor Load (var S : Objects.TStream);
  415.     destructor Done; virtual;
  416.     function   BufChar (P : Word) : Char;
  417.     function   BufPtr (P : Word) : Word;
  418.     procedure  ChangeBounds (var Bounds : TRect); virtual;
  419.     procedure  ConvertEvent (var Event : Drivers.TEvent); virtual;
  420.     function   CursorVisible : Boolean;
  421.     procedure  DeleteSelect;
  422.     procedure  DoneBuffer; virtual;
  423.     procedure  Draw; virtual;
  424.     function   GetPalette : Views.PPalette; virtual;
  425.     procedure  HandleEvent (var Event : Drivers.TEvent); virtual;
  426.     procedure  InitBuffer; virtual;
  427.     function   InsertBuffer (var P : PEditBuffer; Offset, Length : Word;
  428.                                      AllowUndo, SelectText : Boolean) : Boolean;
  429.     function   InsertFrom (Editor : PEditor) : Boolean; virtual;
  430.     function   InsertText (Text : Pointer; Length : Word; SelectText : Boolean) : Boolean;
  431.     procedure  ScrollTo (X, Y : Integer);
  432.     function   Search (FindStr : String; Opts : Word) : Boolean;
  433.     function   SetBufSize (NewSize : Word) : Boolean; virtual;
  434.     procedure  SetCmdState (Command : Word; Enable : Boolean);
  435.     procedure  SetSelect (NewStart, NewEnd : Word; CurStart : Boolean);
  436.     procedure  SetState (AState : Word; Enable : Boolean); virtual;
  437.     procedure  Store (var S : Objects.TStream);
  438.     procedure  TrackCursor (Center : Boolean);
  439.     procedure  Undo;
  440.     procedure  UpdateCommands; virtual;
  441.     function   Valid (Command : Word) : Boolean; virtual;
  442.  
  443.   private
  444.  
  445.     KeyState       : Integer;
  446.     LockCount      : Byte;
  447.     UpdateFlags    : Byte;
  448.  
  449.     { MARK - Start. }
  450.  
  451.     Place_Marker   : Array [1..10] of Word; { Inserted array to hold place markers. }
  452.     Search_Replace : Boolean; { Added boolean to test for Search and Replace insertions. }
  453.  
  454.     { MARK - Stop. }
  455.  
  456.     { CENTER - Start. }
  457.  
  458.     procedure  Center_Text (Select_Mode : Byte);
  459.  
  460.     { CENTER - Stop. } { Added procedure to center a line of text. }
  461.  
  462.     function   CharPos (P, Target : Word) : Integer;
  463.     function   CharPtr (P : Word; Target : Integer) : Word;
  464.  
  465.     { WRAP -   Start. }
  466.  
  467.     procedure  Check_For_Word_Wrap (Select_Mode : Byte; Center_Cursor : Boolean);
  468.  
  469.     { WRAP -   Stop. } { Added procedure to check for word wrap. }
  470.  
  471.     function   ClipCopy : Boolean;
  472.     procedure  ClipCut;
  473.     procedure  ClipPaste;
  474.     procedure  DeleteRange (StartPtr, EndPtr : Word; DelSelect : Boolean);
  475.     procedure  DoSearchReplace;
  476.     procedure  DoUpdate;
  477.  
  478.     { WRAP -   Start. }
  479.  
  480.     function   Do_Word_Wrap (Select_Mode : Byte; Center_Cursor : Boolean) : Boolean;
  481.  
  482.     { WRAP -   Stop. } { Added procedure to check for word wrap. }
  483.  
  484.     procedure  DrawLines (Y, Count : Integer; LinePtr : Word);
  485.     procedure  FormatLine (var DrawBuf; LinePtr : Word; Width : Integer; Colors : Word);
  486.     procedure  Find;
  487.     function   GetMousePtr (Mouse : Objects.TPoint) : Word;
  488.     function   HasSelection : Boolean;
  489.     procedure  HideSelect;
  490.  
  491.     { INSLIN - Start. }
  492.  
  493.     procedure  Insert_Line (Select_Mode : Byte);
  494.  
  495.     { INSLIN - Stop. } { Added procedure to insert line at cursor. }
  496.  
  497.     function   IsClipboard : Boolean;
  498.  
  499.     { MARK -   Start. }
  500.  
  501.     procedure  Jump_Place_Marker (Element : Byte; Select_Mode : Byte);
  502.  
  503.     { MARK -   Stop. } { Added procedure to jump to a place marker if ^Q# is pressed. }
  504.  
  505.     { JLINE -  Start }
  506.  
  507.     procedure  Jump_To_Line  (Select_Mode : Byte);
  508.  
  509.     { JLINE -  Stop. }
  510.  
  511.     function   LineEnd (P : Word) : Word;
  512.     function   LineMove (P : Word; Count : Integer) : Word;
  513.     function   LineStart (P : Word) : Word;
  514.     procedure  Lock;
  515.  
  516.     { WRAP -   Start. }
  517.  
  518.     function NewLine (Select_Mode : Byte) : Boolean;
  519.  
  520.     { WRAP -   Stop. } { Included a new parameter. }
  521.  
  522.     function   NextChar (P : Word) : Word;
  523.     function   NextLine (P : Word) : Word;
  524.     function   NextWord (P : Word) : Word;
  525.     function   PrevChar (P : Word) : Word;
  526.     function   PrevLine (P : Word) : Word;
  527.     function   PrevWord (P : Word) : Word;
  528.  
  529.     { REFDOC - Start. }
  530.  
  531.     procedure  Reformat_Document (Select_Mode : Byte; Center_Cursor : Boolean);
  532.  
  533.     { REFDOC - Stop. } { Added procedure to allow document reformatting. }
  534.  
  535.     { REFORM - Start. }
  536.  
  537.     function   Reformat_Paragraph (Select_Mode   : Byte;
  538.                                    Center_Cursor : Boolean) : Boolean;
  539.  
  540.     { REFORM - Stop. } { Added procedure to reformat paragraphs. }
  541.  
  542.     { WRAP -   Start. }
  543.  
  544.     procedure  Remove_EOL_Spaces (Select_Mode : Byte);
  545.  
  546.     { WRAP -   Stop. }  { Added procedure to remove spaces at end of a line. }
  547.  
  548.     procedure  Replace;
  549.  
  550.     { SCRLDN - Start. }
  551.  
  552.     procedure  Scroll_Down;
  553.  
  554.     { SCRLDN - Stop. }
  555.  
  556.     { SCRLUP - Start. }
  557.  
  558.     procedure  Scroll_Up;
  559.  
  560.     { SCRLUP - Stop. }
  561.  
  562.     { SELWRD - Start. }
  563.  
  564.     procedure  Select_Word;
  565.  
  566.     { SELWRD - Stop. } { Added procedure to allow selecting a word only. }
  567.  
  568.     procedure  SetBufLen (Length : Word);
  569.     procedure  SetCurPtr (P : Word; SelectMode : Byte);
  570.  
  571.     { MARK -   Start. }
  572.  
  573.     procedure  Set_Place_Marker (Element : Byte);
  574.  
  575.     { MARK -   Stop. } { Added procedure to set a Place_Marker if ^K# is pressed. }
  576.  
  577.     { RMSET -  Start. }
  578.  
  579.     procedure  Set_Right_Margin;
  580.  
  581.     { RMSET -  Stop. } { Added procedure to set Right_Margin via a dialog box. }
  582.  
  583.     { PRETAB - Start. }
  584.  
  585.     procedure  Set_Tabs;
  586.  
  587.     { PRETAB - Stop. } { Added procedure to allow preset tabs. }
  588.  
  589.     procedure  StartSelect;
  590.  
  591.     { PRETAB - Start. }
  592.  
  593.     procedure  Tab_Key (Select_Mode : Byte);
  594.  
  595.     { PRETAB - Stop. } { Added procedure to process Tab key as spaces or movment. }
  596.  
  597.     procedure  ToggleInsMode;
  598.     procedure  Unlock;
  599.     procedure  Update (AFlags : Byte);
  600.  
  601.     { MARK -   Start. }
  602.  
  603.     procedure  Update_Place_Markers (AddCount : Word; KillCount : Word;
  604.                                      StartPtr : Word;    EndPtr : Word);
  605.  
  606.     { MARK -   Stop. } { Added procedure to update Place_Marker as we change text. }
  607.  
  608.   end;
  609.  
  610.  
  611.  
  612. TYPE
  613.  
  614.   TMemoData = record
  615.  
  616.     Length : Word;
  617.     Buffer : TEditBuffer;
  618.  
  619.   end;
  620.  
  621.  
  622.  
  623. TYPE
  624.  
  625.   PMemo = ^TMemo;
  626.   TMemo = object (TEditor)
  627.  
  628.     constructor Load (var S : Objects.TStream);
  629.     function    DataSize : Word; virtual;
  630.     procedure   GetData (var Rec); virtual;
  631.     function    GetPalette : Views.PPalette; virtual;
  632.     procedure   HandleEvent (var Event : Drivers.TEvent); virtual;
  633.     procedure   SetData (var Rec); virtual;
  634.     procedure   Store (var S : Objects.TStream);
  635.  
  636.   end;
  637.  
  638.  
  639.  
  640. TYPE
  641.  
  642.   PFileEditor = ^TFileEditor;
  643.   TFileEditor = object (TEditor)
  644.  
  645.     FileName : FNameStr;
  646.  
  647.     constructor Init (var Bounds : TRect; AHScrollBar, AVScrollBar : PScrollBar;
  648.                           AIndicator : PIndicator; AFileName : FNameStr);
  649.     constructor Load (var S : Objects.TStream);
  650.     procedure   DoneBuffer; virtual;
  651.     procedure   HandleEvent (var Event : Drivers.TEvent); virtual;
  652.     procedure   InitBuffer; virtual;
  653.     function    LoadFile : Boolean;
  654.     function    Save : Boolean;
  655.     function    SaveAs : Boolean;
  656.     function    SaveFile : Boolean;
  657.     function    SetBufSize (NewSize : Word) : Boolean; virtual;
  658.     procedure   Store (var S : Objects.TStream);
  659.     procedure   UpdateCommands; virtual;
  660.     function    Valid (Command : Word) : Boolean; virtual;
  661.  
  662.   end;
  663.  
  664.  
  665.  
  666. TYPE
  667.  
  668.   PEditWindow = ^TEditWindow;
  669.   TEditWindow = object (TWindow)
  670.  
  671.     Editor : PFileEditor;
  672.  
  673.     constructor Init (var Bounds : TRect; FileName : FNameStr; ANumber : Integer);
  674.     constructor Load (var S : Objects.TStream);
  675.     procedure   Close; virtual;
  676.     function    GetTitle (MaxSize : Integer) : Views.TTitleStr; virtual;
  677.     procedure   HandleEvent (var Event : Drivers.TEvent); virtual;
  678.     procedure   Store (var S : Objects.TStream);
  679.  
  680.   end;
  681.  
  682.  
  683.  
  684. function DefEditorDialog (Dialog : Integer; Info : Pointer) : Word;
  685.  
  686.  
  687.  
  688. CONST
  689.  
  690.   { PRETAB - Start. }
  691.   { WRAP   - Start. }
  692.  
  693.   WordChars    : set of Char = ['!'..#255];
  694.  
  695.   { WRAP   - Stop. }
  696.   { PRETAB - Stop. } { Changed set parameters to allow punctuation. }
  697.  
  698.  
  699.  
  700.   { ------------------------------------------------- }
  701.   {                                                   }
  702.   { The Allow_Reformat boolean is a programmer hook.  }
  703.   { I've placed this here to allow programmers to     }
  704.   { determine whether or not paragraph and document   }
  705.   { reformatting are allowed if Word_Wrap is not      }
  706.   { active.  Some people say don't allow, and others  }
  707.   { say allow it.  I've left it up to the programmer. }
  708.   { Set to FALSE if not allowed, or TRUE if allowed.  }
  709.   {                                                   }
  710.   { ------------------------------------------------- }
  711.  
  712.   Allow_Reformat : Boolean = True;
  713.  
  714.   EditorDialog   : TEditorDialog = DefEditorDialog;
  715.   EditorFlags    : Word = efBackupFiles + efPromptOnReplace;
  716.   FindStr        : String[80] = '';
  717.   ReplaceStr     : String[80] = '';
  718.   Clipboard      : PEditor = nil;
  719.  
  720.  
  721.  
  722. TYPE
  723.  
  724.   TFindDialogRec = record
  725.  
  726.     Find    : String[80];
  727.     Options : Word;
  728.  
  729.   end;
  730.  
  731.  
  732.  
  733.   TReplaceDialogRec = record
  734.  
  735.        Find : String[80];
  736.     Replace : String[80];
  737.     Options : Word;
  738.  
  739.   end;
  740.  
  741.  
  742.  
  743.   { RMSET - Start. }
  744.  
  745.   TRightMarginRec = record
  746.  
  747.     Margin_Position : String[3];
  748.  
  749.   end;
  750.  
  751.   { RMSET - Stop. } { Record required by Right_Margin_Dialog. }
  752.  
  753.  
  754.  
  755.   { PRETAB - Start. }
  756.  
  757.   TTabStopRec = record
  758.  
  759.     Tab_String : String [Tab_Stop_Length];
  760.  
  761.   end;
  762.  
  763.   { PRETAB - Stop. } { Record required by Tab_Stop_Dialog. }
  764.  
  765.  
  766.  
  767. CONST { VMT constants. }
  768.  
  769.   REditor   : TStreamRec = (ObjType : 70;
  770.                             VmtLink : Ofs (TypeOf (TEditor)^);
  771.                                Load : @TEditor.Load;
  772.                               Store : @TEditor.Store);
  773.  
  774.  
  775.   RMemo     : TStreamRec = (ObjType : 71;
  776.                             VmtLink : Ofs (TypeOf (TMemo)^);
  777.                                Load : @TMemo.Load;
  778.                               Store : @TMemo.Store);
  779.  
  780.  
  781.   RFileEditor : TStreamRec = (ObjType : 72;
  782.                               VmtLink : Ofs (TypeOf (TFileEditor)^);
  783.                                  Load : @TFileEditor.Load;
  784.                                 Store : @TFileEditor.Store);
  785.  
  786.  
  787.   RIndicator : TStreamRec = (ObjType : 73;
  788.                              VmtLink : Ofs (TypeOf (TIndicator)^);
  789.                                 Load : @TIndicator.Load;
  790.                                Store : @TIndicator.Store);
  791.  
  792.  
  793.   REditWindow : TStreamRec = (ObjType : 74;
  794.                               VmtLink : Ofs (TypeOf (TEditWindow)^);
  795.                                  Load : @TEditWindow.Load;
  796.                                 Store : @TEditWindow.Store);
  797.  
  798.  
  799.  
  800. procedure RegisterEditors;
  801.  
  802.  
  803.  
  804.  
  805. implementation
  806.  
  807.  
  808.  
  809. uses
  810.  
  811.   Memory,
  812.   Buffers,
  813.   Dos;
  814.  
  815.  
  816.  
  817. CONST { Update flag constants. }
  818.  
  819.   ufUpdate = $01;
  820.   ufLine   = $02;
  821.   ufView   = $04;
  822.  
  823.   { STATS - Start. }
  824.  
  825.   ufStats  = $05;
  826.  
  827.   { STATS - Stop. }
  828.  
  829.  
  830.  
  831. CONST { SelectMode constants. }
  832.  
  833.   smExtend = $01;
  834.   smDouble = $02;
  835.  
  836.  
  837.  
  838. CONST
  839.  
  840.   sfSearchFailed = $FFFF;
  841.  
  842.  
  843.  
  844. CONST { Arrays that hold all the command keys and options. }
  845.  
  846.   { CTRLBK - Start. }
  847.   { HOMEND - Start. }
  848.   { INDENT - Start. }
  849.   { INSLIN - Start. }
  850.   { JLINE  - Start. }
  851.   { PRETAB - Start. }
  852.   { REFORM - Start. }
  853.   { SCRLDN - Start. }
  854.   { SCRLDN - Start. }
  855.  
  856.   FirstKeys : array[0..46 * 2] of Word = (46, Ord (^A),    cmWordLeft,
  857.                                               Ord (^B),    cmReformPara,
  858.                                               Ord (^C),    cmPageDown,
  859.                                               Ord (^D),    cmCharRight,
  860.                                               Ord (^E),    cmLineUp,
  861.                                               Ord (^F),    cmWordRight,
  862.                                               Ord (^G),    cmDelChar,
  863.                                               Ord (^H),    cmBackSpace,
  864.                                               Ord (^I),    cmTabKey,
  865.                                               Ord (^J),    $FF04,
  866.                                               Ord (^K),    $FF02,
  867.                                               Ord (^L),    cmSearchAgain,
  868.                                               Ord (^M),    cmNewLine,
  869.                                               Ord (^N),    cmInsertLine,
  870.                                               Ord (^O),    $FF03,
  871.                                               Ord (^Q),    $FF01,
  872.                                               Ord (^R),    cmPageUp,
  873.                                               Ord (^S),    cmCharLeft,
  874.                                               Ord (^T),    cmDelWord,
  875.                                               Ord (^U),    cmUndo,
  876.                                               Ord (^V),    cmInsMode,
  877.                                               Ord (^W),    cmScrollUp,
  878.                                               Ord (^X),    cmLineDown,
  879.                                               Ord (^Y),    cmDelLine,
  880.                                               Ord (^Z),    cmScrollDown,
  881.                                               kbLeft,      cmCharLeft,
  882.                                               kbRight,     cmCharRight,
  883.                                               kbCtrlLeft,  cmWordLeft,
  884.                                               kbCtrlRight, cmWordRight,
  885.                                               kbHome,      cmLineStart,
  886.                                               kbEnd,       cmLineEnd,
  887.                                               kbCtrlHome,  cmHomePage,
  888.                                               kbCtrlEnd,   cmEndPage,
  889.                                               kbUp,        cmLineUp,
  890.                                               kbDown,      cmLineDown,
  891.                                               kbPgUp,      cmPageUp,
  892.                                               kbPgDn,      cmPageDown,
  893.                                               kbCtrlPgUp,  cmTextStart,
  894.                                               kbCtrlPgDn,  cmTextEnd,
  895.                                               kbIns,       cmInsMode,
  896.                                               kbDel,       cmDelChar,
  897.                                               kbCtrlBack,  cmDelStart,
  898.                                               kbShiftIns,  cmPaste,
  899.                                               kbShiftDel,  cmCut,
  900.                                               kbCtrlIns,   cmCopy,
  901.                                               kbCtrlDel,   cmClear);
  902.  
  903.   { SCRLUP - Stop. } { Added ^W to scroll screen up.         }
  904.   { SCRLDN - Stop. } { Added ^Z to scroll screen down.       }
  905.   { REFORM - Stop. } { Added ^B for paragraph reformatting.  }
  906.   { PRETAB - Stop. } { Added ^I for preset tabbing.          }
  907.   { JLINE  - Stop. } { Added ^J to jump to a line number.    }
  908.   { INSLIN - Stop. } { Added ^N to insert line at cursor.    }
  909.   { INDENT - Stop. } { Removed ^O and put it into ^QI.       }
  910.   { HOMEND - Stop. } { Added kbCtrlHome and kbCtrlEnd pages. }
  911.   { CTRLBK - Stop. } { Added kbCtrlBack same as ^QH.         }
  912.  
  913.   { INDENT - Start. }
  914.   { MARK   - Start. }
  915.   { REFDOC - Start. }
  916.   { UNDO   - Start. }
  917.  
  918.   QuickKeys : array[0..21 * 2] of Word = (21, Ord ('0'), cmJumpMark0,
  919.                                               Ord ('1'), cmJumpMark1,
  920.                                               Ord ('2'), cmJumpMark2,
  921.                                               Ord ('3'), cmJumpMark3,
  922.                                               Ord ('4'), cmJumpMark4,
  923.                                               Ord ('5'), cmJumpMark5,
  924.                                               Ord ('6'), cmJumpMark6,
  925.                                               Ord ('7'), cmJumpMark7,
  926.                                               Ord ('8'), cmJumpMark8,
  927.                                               Ord ('9'), cmJumpMark9,
  928.                                               Ord ('A'), cmReplace,
  929.                                               Ord ('C'), cmTextEnd,
  930.                                               Ord ('D'), cmLineEnd,
  931.                                               Ord ('F'), cmFind,
  932.                                               Ord ('H'), cmDelStart,
  933.                                               Ord ('I'), cmIndentMode,
  934.                                               Ord ('L'), cmUndo,
  935.                                               Ord ('R'), cmTextStart,
  936.                                               Ord ('S'), cmLineStart,
  937.                                               Ord ('U'), cmReformDoc,
  938.                                               Ord ('Y'), cmDelEnd);
  939.  
  940.   { UNDO   - Stop. } { Added IDE undo feature of ^QL.                  }
  941.   { REFDOC - Stop. } { Added document reformat feature if ^QU pressed. }
  942.   { MARK   - Stop. } { Added cmJumpMark# to allow place marking.       }
  943.   { INDENT - Stop. } { Moved IndentMode here from Firstkeys.           }
  944.  
  945.   { MARK   - Start. }
  946.   { SAVE   - Start. }
  947.   { SELWRD - Start. }
  948.  
  949.   BlockKeys : array[0..20 * 2] of Word = (20, Ord ('0'), cmSetMark0,
  950.                                               Ord ('1'), cmSetMark1,
  951.                                               Ord ('2'), cmSetMark2,
  952.                                               Ord ('3'), cmSetMark3,
  953.                                               Ord ('4'), cmSetMark4,
  954.                                               Ord ('5'), cmSetMark5,
  955.                                               Ord ('6'), cmSetMark6,
  956.                                               Ord ('7'), cmSetMark7,
  957.                                               Ord ('8'), cmSetMark8,
  958.                                               Ord ('9'), cmSetMark9,
  959.                                               Ord ('B'), cmStartSelect,
  960.                                               Ord ('C'), cmPaste,
  961.                                               Ord ('D'), cmSave,
  962.                                               Ord ('F'), cmSaveAs,
  963.                                               Ord ('H'), cmHideSelect,
  964.                                               Ord ('K'), cmCopy,
  965.                                               Ord ('S'), cmSave,
  966.                                               Ord ('T'), cmSelectWord,
  967.                                               Ord ('Y'), cmCut,
  968.                                               Ord ('X'), cmSaveDone);
  969.  
  970.   { SELWRD - Stop. } { Added ^KT to select word only. }
  971.   { SAVE   - Stop. } { Added ^KD, ^KF, ^KS, ^KX key commands.   }
  972.   { MARK   - Stop. } { Added cmSetMark# to allow place marking. }
  973.  
  974.   { CENTER - Start. }
  975.   { PRETAB - Start. }
  976.   { RMSET  - Start. }
  977.   { WRAP   - Start. }
  978.  
  979.   FormatKeys : array[0..4 * 2] of Word = (4,  Ord ('C'), cmCenterText,
  980.                                               Ord ('I'), cmSetTabs,
  981.                                               Ord ('R'), cmRightMargin,
  982.                                               Ord ('W'), cmWordWrap);
  983.  
  984.   { WRAP   - Stop. } { Added Wordwrap feature if ^OW pressed.          }
  985.   { RMSET  - Stop. } { Added set right margin feature if ^OR pressed.  }
  986.   { PRETAB - Stop. } { Added preset tab feature if ^OI pressed.        }
  987.   { CENTER - Stop. } { Added center text option ^OC for a line.        }
  988.  
  989.  
  990.  
  991.   { JLINE - Start. }
  992.  
  993.   JumpKeys : array[0..1 * 2] of Word = (1, Ord ('L'), cmJumpLine);
  994.  
  995.   { JLINE - Stop. } { Added jump to line number feature if ^JL pressed. }
  996.  
  997.  
  998.  
  999.   { CENTER - Start. }
  1000.   { JLINE  - Start. }
  1001.   { PRETAB - Start. }
  1002.   { WRAP   - Start. }
  1003.  
  1004.   KeyMap : array[0..4] of Pointer = (@FirstKeys,
  1005.                                      @QuickKeys,
  1006.                                      @BlockKeys,
  1007.                                      @FormatKeys,
  1008.                                      @JumpKeys);
  1009.  
  1010.   { WRAP   - Stop. } { Added @FormatKeys for new ^O? keys. }
  1011.   { PRETAB - Stop. } { Added @FormatKeys for new ^O? keys. }
  1012.   { JLINE  - Stop. } { Added @JumpKeys for new ^J? keys.   }
  1013.   { CENTER - Stop. } { Added @FormatKeys for new ^O? keys. }
  1014.  
  1015.  
  1016.  
  1017. { -------------------------------------------------------------------------- }
  1018.  
  1019.  
  1020.  
  1021. function DefEditorDialog (Dialog : Integer; Info : Pointer) : Word;
  1022.  
  1023. begin
  1024.  
  1025.   DefEditorDialog := Views.cmCancel;
  1026.  
  1027.  
  1028. end; { DefEditorDialog }
  1029.  
  1030.  
  1031.  
  1032. { -------------------------------------------------------------------------- }
  1033.  
  1034.  
  1035.  
  1036. function Min (X, Y : Integer) : Integer; assembler;
  1037.  
  1038. asm
  1039.         MOV     AX,X
  1040.         CMP     AX,Y
  1041.         JLE     @@1
  1042.         MOV     AX,Y
  1043. @@1:
  1044.  
  1045.  
  1046. end; { Min }
  1047.  
  1048.  
  1049.  
  1050. { -------------------------------------------------------------------------- }
  1051.  
  1052.  
  1053.  
  1054. function Max (X, Y : Integer) : Integer; assembler;
  1055.  
  1056. asm
  1057.         MOV     AX,X
  1058.         CMP     AX,Y
  1059.         JGE     @@1
  1060.         MOV     AX,Y
  1061. @@1:
  1062.  
  1063.  
  1064. end; { Max }
  1065.  
  1066.  
  1067.  
  1068. { -------------------------------------------------------------------------- }
  1069.  
  1070.  
  1071.  
  1072. function MinWord (X, Y : Word) : Word; assembler;
  1073.  
  1074. asm
  1075.         MOV     AX,X
  1076.         CMP     AX,Y
  1077.         JBE     @@1
  1078.         MOV     AX,Y
  1079. @@1:
  1080.  
  1081.  
  1082. end; { MinWord }
  1083.  
  1084.  
  1085.  
  1086. { -------------------------------------------------------------------------- }
  1087.  
  1088.  
  1089.  
  1090. function MaxWord (X, Y : Word) : Word; assembler;
  1091.  
  1092. asm
  1093.         MOV     AX,X
  1094.         CMP     AX,Y
  1095.         JAE     @@1
  1096.         MOV     AX,Y
  1097. @@1:
  1098.  
  1099.  
  1100. end; { MaxWord }
  1101.  
  1102.  
  1103.  
  1104. { -------------------------------------------------------------------------- }
  1105.  
  1106.  
  1107.  
  1108. function CountLines (var Buf; Count : Word) : Integer; assembler;
  1109.  
  1110. asm
  1111.         LES     DI,Buf
  1112.         MOV     CX,Count
  1113.         XOR     DX,DX
  1114.         MOV     AL,0DH
  1115.         CLD
  1116. @@1:    JCXZ    @@2
  1117.         REPNE   SCASB
  1118.         JNE     @@2
  1119.         INC     DX
  1120.         JMP     @@1
  1121. @@2:    MOV     AX,DX
  1122.  
  1123.  
  1124. end; { CountLines }
  1125.  
  1126.  
  1127.  
  1128. { -------------------------------------------------------------------------- }
  1129.  
  1130.  
  1131.  
  1132. function ScanKeyMap (KeyMap : Pointer; KeyCode : Word) : Word; assembler;
  1133.  
  1134. asm
  1135.         PUSH    DS
  1136.         LDS     SI,KeyMap
  1137.         MOV     DX,KeyCode
  1138.         CLD
  1139.         LODSW
  1140.         MOV     CX,AX
  1141. @@1:    LODSW
  1142.         MOV     BX,AX
  1143.         LODSW
  1144.         CMP     BL,DL
  1145.         JNE     @@3
  1146.         OR      BH,BH
  1147.         JE      @@4
  1148.         CMP     BH,DH
  1149.         JE      @@4
  1150. @@3:    LOOP    @@1
  1151.         XOR     AX,AX
  1152. @@4:    POP     DS
  1153.  
  1154.  
  1155. end; { ScanKeyMap }
  1156.  
  1157.  
  1158.  
  1159. { -------------------------------------------------------------------------- }
  1160.  
  1161.  
  1162.  
  1163. function Scan (var Block; Size : Word; Str : String) : Word; assembler;
  1164.  
  1165. asm
  1166.         PUSH    DS
  1167.         LES     DI,Block
  1168.         LDS     SI,Str
  1169.         MOV     CX,Size
  1170.         JCXZ    @@3
  1171.         CLD
  1172.         LODSB
  1173.         CMP     AL,1
  1174.         JB      @@5
  1175.         JA      @@1
  1176.         LODSB
  1177.         REPNE   SCASB
  1178.         JNE     @@3
  1179.         JMP     @@5
  1180. @@1:    XOR     AH,AH
  1181.         MOV     BX,AX
  1182.         DEC     BX
  1183.         MOV     DX,CX
  1184.         SUB     DX,AX
  1185.         JB      @@3
  1186.         LODSB
  1187.         INC     DX
  1188.         INC     DX
  1189. @@2:    DEC     DX
  1190.         MOV     CX,DX
  1191.         REPNE   SCASB
  1192.         JNE     @@3
  1193.         MOV     DX,CX
  1194.         MOV     CX,BX
  1195.         REP     CMPSB
  1196.         JE      @@4
  1197.         SUB     CX,BX
  1198.         ADD     SI,CX
  1199.         ADD     DI,CX
  1200.         INC     DI
  1201.         OR      DX,DX
  1202.         JNE     @@2
  1203. @@3:    XOR     AX,AX
  1204.         JMP     @@6
  1205. @@4:    SUB     DI,BX
  1206. @@5:    MOV     AX,DI
  1207.         SUB     AX,WORD PTR Block
  1208. @@6:    DEC     AX
  1209.         POP     DS
  1210.  
  1211.  
  1212. end; { Scan }
  1213.  
  1214.  
  1215.  
  1216. { -------------------------------------------------------------------------- }
  1217.  
  1218.  
  1219.  
  1220. function IScan (var Block; Size : Word; Str : String) : Word; assembler;
  1221.  
  1222. VAR
  1223.  
  1224.   S : String;
  1225.  
  1226. asm
  1227.         PUSH    DS
  1228.         MOV     AX,SS
  1229.         MOV     ES,AX
  1230.         LEA     DI,S
  1231.         LDS     SI,Str
  1232.         XOR     AH,AH
  1233.         LODSB
  1234.         STOSB
  1235.         MOV     CX,AX
  1236.         MOV     BX,AX
  1237.         JCXZ    @@9
  1238. @@1:    LODSB
  1239.         CMP     AL,'a'
  1240.         JB      @@2
  1241.         CMP     AL,'z'
  1242.         JA      @@2
  1243.         SUB     AL,20H
  1244. @@2:    STOSB
  1245.         LOOP    @@1
  1246.         SUB     DI,BX
  1247.         LDS     SI,Block
  1248.         MOV     CX,Size
  1249.         JCXZ    @@8
  1250.         CLD
  1251.         SUB     CX,BX
  1252.         JB      @@8
  1253.         INC     CX
  1254. @@4:    MOV     AH,ES:[DI]
  1255.         AND     AH,$DF
  1256. @@5:    LODSB
  1257.         AND     AL,$DF
  1258.         CMP     AL,AH
  1259.         LOOPNE  @@5
  1260.         JNE     @@8
  1261.         DEC     SI
  1262.         MOV     DX,CX
  1263.         MOV     CX,BX
  1264. @@6:    REPE    CMPSB
  1265.         JE      @@10
  1266.         MOV     AL,DS:[SI-1]
  1267.         CMP     AL,'a'
  1268.         JB      @@7
  1269.         CMP     AL,'z'
  1270.         JA      @@7
  1271.         SUB     AL,20H
  1272. @@7:    CMP     AL,ES:[DI-1]
  1273.         JE      @@6
  1274.         SUB     CX,BX
  1275.         ADD     SI,CX
  1276.         ADD     DI,CX
  1277.         INC     SI
  1278.         MOV     CX,DX
  1279.         TEST    CX,CX
  1280.         JNE     @@4
  1281. @@8:    XOR     AX,AX
  1282.         JMP     @@11
  1283. @@9:    MOV     AX, 1
  1284.         JMP     @@11
  1285. @@10:   SUB     SI,BX
  1286.         MOV     AX,SI
  1287.         SUB     AX,WORD PTR Block
  1288.         INC     AX
  1289. @@11:   DEC     AX
  1290.         POP     DS
  1291.  
  1292.  
  1293. end; { Iscan }
  1294.  
  1295.  
  1296.  
  1297. { -------------------------------------------------------------------------- }
  1298.  
  1299.  
  1300.  
  1301.          { ---------------------------------------------------- }
  1302.          {                                                      }
  1303.          { The following methods are for the TINDICATOR object. }
  1304.          {                                                      }
  1305.          { ---------------------------------------------------- }
  1306.  
  1307.  
  1308.  
  1309. constructor TIndicator.Init (var Bounds : TRect);
  1310.  
  1311. VAR
  1312.  
  1313.   R : TRect;
  1314.  
  1315. begin
  1316.  
  1317.   TView.Init (Bounds);
  1318.   GrowMode := gfGrowLoY + gfGrowHiY;
  1319.  
  1320.  
  1321.  
  1322. end; { TIndicator.Init }
  1323.  
  1324.  
  1325.  
  1326. { -------------------------------------------------------------------------- }
  1327.  
  1328.  
  1329.  
  1330. procedure TIndicator.Draw;
  1331.  
  1332. VAR
  1333.  
  1334.   Color : Byte;
  1335.   Frame : Char;
  1336.   L     : array[0..1] of Longint;
  1337.   S     : String[15];
  1338.   B     : Views.TDrawBuffer;
  1339.  
  1340. begin
  1341.  
  1342.   if State and sfDragging = 0 then
  1343.     begin
  1344.       Color := GetColor (1);
  1345.       Frame := #205;
  1346.     end
  1347.   else
  1348.     begin
  1349.       Color := GetColor (2);
  1350.       Frame := #196;
  1351.     end;
  1352.  
  1353.   MoveChar (B, Frame, Color, Size.X);
  1354.  
  1355.  
  1356.  
  1357.   { STATS - Start. }
  1358.  
  1359.   { -------------------------------------------------------------------- }
  1360.   {                                                                      }
  1361.   { If the text has been modified, put an 'M' in the TIndicator display. }
  1362.   {                                                                      }
  1363.   { -------------------------------------------------------------------- }
  1364.  
  1365.  
  1366.   if Modified then
  1367.     WordRec (B[1]).Lo := 77;
  1368.  
  1369.  
  1370.  
  1371.   { ---------------------------------------------------------- }
  1372.   {                                                            }
  1373.   { If WordWrap is active put a 'W' in the TIndicator display. }
  1374.   { Otherwise, just use the current frame character.           }
  1375.   {                                                            }
  1376.   { ---------------------------------------------------------- }
  1377.  
  1378.  
  1379.   if WordWrap then
  1380.     WordRec (B[2]).Lo := 87
  1381.   else
  1382.     WordRec (B[2]).Lo := Byte (Frame);
  1383.  
  1384.  
  1385.  
  1386.   { --------------------------------------------------------- }
  1387.   {                                                           }
  1388.   { If AutoIndent is active put an 'I' in TIndicator display. }
  1389.   { Otherwise, just use the current frame character.          }
  1390.   {                                                           }
  1391.   { --------------------------------------------------------- }
  1392.  
  1393.  
  1394.   if AutoIndent then
  1395.     WordRec (B[0]).Lo := 73
  1396.   else
  1397.     WordRec (B[0]).Lo := Byte (Frame);
  1398.  
  1399.   L[0] := Location.Y + 1;
  1400.   L[1] := Location.X + 1;
  1401.  
  1402.   FormatStr (S, ' %d:%d ', L);
  1403.   MoveStr (B[9 - Pos (':', S)], S, Color);       { Changed original 8 to 9. }
  1404.   WriteBuf (0, 0, Size.X, 1, B);
  1405.  
  1406.   { STATS - Stop. } { Changed who goes where in B array and added new code. }
  1407.  
  1408.  
  1409. end; { TIndicator.Draw }
  1410.  
  1411.  
  1412.  
  1413. { -------------------------------------------------------------------------- }
  1414.  
  1415.  
  1416.  
  1417. function TIndicator.GetPalette : Views.PPalette;
  1418.  
  1419. CONST
  1420.  
  1421.   P : string[Length (CIndicator)] = CIndicator;
  1422.  
  1423. begin
  1424.  
  1425.   GetPalette := @P;
  1426.  
  1427.  
  1428. end; { TIndicator.GetPalette }
  1429.  
  1430.  
  1431.  
  1432. { -------------------------------------------------------------------------- }
  1433.  
  1434.  
  1435.  
  1436. procedure TIndicator.SetState (AState : Word; Enable : Boolean);
  1437.  
  1438. begin
  1439.  
  1440.   TView.SetState (AState, Enable);
  1441.   if AState = sfDragging
  1442.     then DrawView;
  1443.  
  1444.  
  1445. end; { TIndicator.SetState }
  1446.  
  1447.  
  1448.  
  1449. { -------------------------------------------------------------------------- }
  1450.  
  1451.  
  1452.  
  1453. { STATS - Start. }
  1454.  
  1455. procedure TIndicator.SetValue (ALocation : Objects.TPoint; IsAutoIndent : Boolean;
  1456.                                                            IsModified   : Boolean;
  1457.                                                            IsWordWrap   : Boolean);
  1458.  
  1459. begin
  1460.  
  1461.   if   (Longint (Location) <> Longint (ALocation))
  1462.     or (AutoIndent <> IsAutoIndent)
  1463.     or (Modified <> IsModified)
  1464.     or (WordWrap <> IsWordWrap) then
  1465.   begin
  1466.     Location   := ALocation;
  1467.     AutoIndent := IsAutoIndent;    { Added provisions to show AutoIndent. }
  1468.     Modified   := IsModified;
  1469.     WordWrap   := IsWordWrap;      { Added provisions to show WordWrap.   }
  1470.  
  1471.     DrawView;
  1472.   end;
  1473.  
  1474.  
  1475. end; { TIndicator.SetValue }
  1476.  
  1477. { STATS - Stop. } { Changed parameter calls to show them on TIndicator line. }
  1478.  
  1479.  
  1480.  
  1481. { -------------------------------------------------------------------------- }
  1482.  
  1483.  
  1484.  
  1485.          { ------------------------------------------------- }
  1486.          {                                                   }
  1487.          { The following methods are for the TEDITOR object. }
  1488.          {                                                   }
  1489.          { ------------------------------------------------- }
  1490.  
  1491.  
  1492.  
  1493. constructor TEditor.Init (var Bounds : TRect;
  1494.                               AHScrollBar, AVScrollBar : PScrollBar;
  1495.                               AIndicator : PIndicator; ABufSize : Word);
  1496.  
  1497. { MARK - Start. }
  1498.  
  1499. VAR
  1500.  
  1501.   Element : Byte;      { Place_Marker array element to initialize array with. }
  1502.  
  1503. { MARK - Stop. } { Added Element variable. }
  1504.  
  1505. begin
  1506.  
  1507.   TView.Init (Bounds);
  1508.   GrowMode := gfGrowHiX + gfGrowHiY;
  1509.   Options := Options or ofSelectable;
  1510.   EventMask := evMouseDown + evKeyDown + evCommand + evBroadcast;
  1511.   ShowCursor;
  1512.  
  1513.   HScrollBar := AHScrollBar;
  1514.   VScrollBar := AVScrollBar;
  1515.  
  1516.   Indicator := AIndicator;
  1517.   BufSize := ABufSize;
  1518.   CanUndo := True;
  1519.   InitBuffer;
  1520.  
  1521.   if Buffer <> nil then
  1522.     IsValid := True
  1523.   else
  1524.     begin
  1525.       EditorDialog (edOutOfMemory, nil);
  1526.       BufSize := 0;
  1527.     end;
  1528.  
  1529.   SetBufLen (0);
  1530.  
  1531.   { MARK - Start. }
  1532.  
  1533.   for Element := 1 to 10 do
  1534.     Place_Marker[Element] := 0;
  1535.  
  1536.   { MARK - Stop. } { Added code to initialize Place_Marker array to zero's. }
  1537.  
  1538.   { PRETAB - Start. }
  1539.  
  1540.   Element := 1;
  1541.  
  1542.   while Element <= 70 do
  1543.     begin
  1544.       if Element mod 5 = 0 then
  1545.         Insert ('x', Tab_Settings, Element)
  1546.       else
  1547.         Insert (#32, Tab_Settings, Element);
  1548.       Inc (Element);
  1549.     end;
  1550.  
  1551.   { PRETAB - Stop. }
  1552.  
  1553.   { WRAP - Start. }
  1554.  
  1555.   Right_Margin := 76; { Default Right_Margin value.  Change it if you want another. }
  1556.  
  1557.   { WRAP - Stop. }
  1558.  
  1559.  
  1560. end; { TEditor.Init }
  1561.  
  1562.  
  1563.  
  1564. { -------------------------------------------------------------------------- }
  1565.  
  1566.  
  1567.  
  1568. constructor TEditor.Load (var S : Objects.TStream);
  1569.  
  1570. begin
  1571.  
  1572.   TView.Load (S);
  1573.  
  1574.   GetPeerViewPtr (S, HScrollBar);
  1575.   GetPeerViewPtr (S, VScrollBar);
  1576.   GetPeerViewPtr (S, Indicator);
  1577.   S.Read (BufSize, SizeOf (Word));
  1578.  
  1579.  
  1580.   { LOAD - Start. }
  1581.  
  1582.   { S.Read (CanUndo, SizeOf (Boolean)); }
  1583.  
  1584.   { LOAD - Stop. } { This item caused load/store bug. }
  1585.  
  1586.  
  1587.   { STATS  - Start. }
  1588.   { JLINE  - Start. }
  1589.   { MARK   - Start. }
  1590.   { RMSET  - Start. }
  1591.   { PRETAB - Start. }
  1592.   { WRAP   - Start. }
  1593.  
  1594.   S.Read (AutoIndent,   SizeOf (AutoIndent));
  1595.   S.Read (Line_Number,  SizeOf (Line_Number));
  1596.   S.Read (Place_Marker, SizeOf (Place_Marker));
  1597.   S.Read (Right_Margin, SizeOf (Right_Margin));
  1598.   S.Read (Tab_Settings, SizeOf (Tab_Settings));
  1599.   S.Read (Word_Wrap,    SizeOf (Word_Wrap));
  1600.  
  1601.   CanUndo := True;
  1602.  
  1603.   { WRAP   - Stop. }
  1604.   { PRETAB - Stop. }
  1605.   { RMSET  - Stop. }
  1606.   { MARK   - Stop. }
  1607.   { JLINE  - Stop. }
  1608.   { STATS  - Stop. } { Added these to allow load/store operations. }
  1609.  
  1610.   InitBuffer;
  1611.  
  1612.   if Buffer <> nil then
  1613.     IsValid := True
  1614.   else
  1615.     begin
  1616.       EditorDialog (edOutOfMemory, nil);
  1617.       BufSize := 0;
  1618.     end;
  1619.  
  1620.   Lock;
  1621.  
  1622.   SetBufLen (0);
  1623.  
  1624.  
  1625. end; { TEditor.Load }
  1626.  
  1627.  
  1628.  
  1629. { -------------------------------------------------------------------------- }
  1630.  
  1631.  
  1632.  
  1633. destructor TEditor.Done;
  1634.  
  1635. begin
  1636.  
  1637.   DoneBuffer;
  1638.   TView.Done;
  1639.  
  1640.  
  1641. end; { TEditor.Done }
  1642.  
  1643.  
  1644.  
  1645. { -------------------------------------------------------------------------- }
  1646.  
  1647.  
  1648.  
  1649. function TEditor.BufChar (P : Word) : Char; assembler;
  1650.  
  1651. asm
  1652.         LES     DI,Self
  1653.         MOV     BX,P
  1654.         CMP     BX,ES:[DI].TEditor.CurPtr
  1655.         JB      @@1
  1656.         ADD     BX,ES:[DI].TEditor.GapLen
  1657. @@1:    LES     DI,ES:[DI].TEditor.Buffer
  1658.         MOV     AL,ES:[DI+BX]
  1659.  
  1660.  
  1661. end; { TEditor.BufChar }
  1662.  
  1663.  
  1664.  
  1665. { -------------------------------------------------------------------------- }
  1666.  
  1667.  
  1668.  
  1669. function TEditor.BufPtr (P : Word) : Word; assembler;
  1670.  
  1671. asm
  1672.         LES     DI,Self
  1673.         MOV     AX,P
  1674.         CMP     AX,ES:[DI].TEditor.CurPtr
  1675.         JB      @@1
  1676.         ADD     AX,ES:[DI].TEditor.GapLen
  1677. @@1:
  1678.  
  1679.  
  1680. end; { TEditor.BufPtr }
  1681.  
  1682.  
  1683.  
  1684. { -------------------------------------------------------------------------- }
  1685.  
  1686.  
  1687.  
  1688. { CENTER - Start. }
  1689.  
  1690. procedure TEditor.Center_Text (Select_Mode : Byte);
  1691.  
  1692.  
  1693.   { ---------------------------------------------------- }
  1694.   {                                                      }
  1695.   { This procedure will center the current line of text. }
  1696.   { Centering is based on the current Right_Margin.      }
  1697.   { If the Line_Length exceeds the Right_Margin, or the  }
  1698.   { line is just a blank line, we exit and do nothing.   }
  1699.   {                                                      }
  1700.   { ---------------------------------------------------- }
  1701.  
  1702.  
  1703. VAR
  1704.  
  1705.   Spaces      : array [1..80] of Char;  { Array to hold spaces we'll insert. }
  1706.   Index       : Byte;                   { Index into Spaces array.           }
  1707.   Line_Length : Integer;                { Holds the length of the line.      }
  1708.  
  1709.   E : Word;                             { End of the current line.           }
  1710.   S : Word;                             { Start of the current line.         }
  1711.  
  1712. begin
  1713.  
  1714.   E := LineEnd (CurPtr);
  1715.   S := LineStart (CurPtr);
  1716.  
  1717.  
  1718.  
  1719.   { --------------------------------------------------------- }
  1720.   {                                                           }
  1721.   { If the line is blank (only a CR/LF on it) then do noting. }
  1722.   {                                                           }
  1723.   { --------------------------------------------------------- }
  1724.  
  1725.  
  1726.   if E = S then
  1727.     Exit;
  1728.  
  1729.  
  1730.  
  1731.   { ----------------------------------------------------------------- }
  1732.   {                                                                   }
  1733.   { Set CurPtr to start of line.  Check if line begins with a space.  }
  1734.   { We must strip out any spaces from the beginning, or end of lines. }
  1735.   { If line does not start with space, make sure line length does not }
  1736.   { exceed the Right_Margin.  If it does, then do nothing.            }
  1737.   {                                                                   }
  1738.   { ----------------------------------------------------------------- }
  1739.  
  1740.  
  1741.   SetCurPtr (S, Select_Mode);
  1742.   Remove_EOL_Spaces (Select_Mode);
  1743.  
  1744.   if Buffer^[CurPtr] = #32 then
  1745.     begin
  1746.  
  1747.  
  1748.  
  1749.       { ----------------------------------------------------------------- }
  1750.       {                                                                   }
  1751.       { If the next word is greater than the end of line then do nothing. }
  1752.       { If the line length is greater than Right_Margin then do nothing.  }
  1753.       { Otherwise, delete all spaces at the start of line.                }
  1754.       { Then reset end of line and put CurPtr at start of modified line.  }
  1755.       {                                                                   }
  1756.       { ----------------------------------------------------------------- }
  1757.  
  1758.       E := LineEnd (CurPtr);
  1759.  
  1760.       if NextWord (CurPtr) > E then
  1761.         Exit;
  1762.       if E - NextWord (CurPtr) > Right_Margin then
  1763.         Exit;
  1764.  
  1765.       DeleteRange (CurPtr, NextWord (CurPtr), True);
  1766.  
  1767.       E := LineEnd (CurPtr);
  1768.       SetCurPtr (LineStart (CurPtr), Select_Mode);
  1769.  
  1770.     end
  1771.   else
  1772.     if E - CurPtr > Right_Margin then
  1773.       Exit;
  1774.  
  1775.  
  1776.  
  1777.   { --------------------------------------------------- }
  1778.   {                                                     }
  1779.   { Now we determine the real length of the line.       }
  1780.   { Then we subtract the Line_Length from Right_Margin. }
  1781.   { Dividing the result by two tells us how many spaces }
  1782.   { must be inserted at start of line to center it.     }
  1783.   { When we're all done, set the CurPtr to end of line. }
  1784.   {                                                     }
  1785.   { --------------------------------------------------- }
  1786.  
  1787.  
  1788.   Line_Length := E - CurPtr;
  1789.  
  1790.   for Index := 1 to ((Right_Margin - Line_Length) DIV 2) do
  1791.     Spaces[Index] := #32;
  1792.  
  1793.   InsertText (@Spaces, Index, False);
  1794.   SetCurPtr (LineEnd (CurPtr), Select_Mode);
  1795.  
  1796.  
  1797. end; { TEditor.Center_Text }
  1798.  
  1799. { CENTER - Stop. }
  1800.  
  1801.  
  1802.  
  1803. { -------------------------------------------------------------------------- }
  1804.  
  1805.  
  1806.  
  1807. procedure TEditor.ChangeBounds (var Bounds : TRect);
  1808.  
  1809. begin
  1810.  
  1811.   SetBounds (Bounds);
  1812.   Delta.X := Max (0, Min (Delta.X, Limit.X - Size.X));
  1813.   Delta.Y := Max (0, Min (Delta.Y, Limit.Y - Size.Y));
  1814.   Update (ufView);
  1815.  
  1816.  
  1817. end; { TEditor.ChangeBounds }
  1818.  
  1819.  
  1820.  
  1821. { -------------------------------------------------------------------------- }
  1822.  
  1823.  
  1824.  
  1825. function TEditor.CharPos (P, Target : Word) : Integer;
  1826.  
  1827. VAR
  1828.  
  1829.   Pos : Integer;
  1830.  
  1831. begin
  1832.  
  1833.   Pos := 0;
  1834.  
  1835.   while P < Target do
  1836.   begin
  1837.     if BufChar (P) = #9 then
  1838.       Pos := Pos or 7;
  1839.     Inc (Pos);
  1840.     Inc (P);
  1841.   end;
  1842.  
  1843.   CharPos := Pos;
  1844.  
  1845.  
  1846. end; { TEditor.CharPos }
  1847.  
  1848.  
  1849.  
  1850. { -------------------------------------------------------------------------- }
  1851.  
  1852.  
  1853.  
  1854. function TEditor.CharPtr (P : Word; Target : Integer) : Word;
  1855.  
  1856. VAR
  1857.  
  1858.   Pos : Integer;
  1859.  
  1860. begin
  1861.  
  1862.   Pos := 0;
  1863.  
  1864.   while (Pos < Target) and (P < BufLen) and (BufChar (P) <> #13) do
  1865.   begin
  1866.     if BufChar (P) = #9 then
  1867.       Pos := Pos or 7;
  1868.     Inc (Pos);
  1869.     Inc (P);
  1870.   end;
  1871.  
  1872.   if Pos > Target then
  1873.     Dec (P);
  1874.  
  1875.   CharPtr := P;
  1876.  
  1877.  
  1878. end; { TEditor.CharPtr }
  1879.  
  1880.  
  1881.  
  1882. { -------------------------------------------------------------------------- }
  1883.  
  1884.  
  1885.  
  1886. { WRAP - Start. }
  1887.  
  1888. procedure TEditor.Check_For_Word_Wrap (Select_Mode   : Byte;
  1889.                                        Center_Cursor : Boolean);
  1890.  
  1891.  
  1892.  
  1893.   { ------------------------------------------------- }
  1894.   {                                                   }
  1895.   { This procedure checks if CurPos.X > Right_Margin. }
  1896.   { If it is, then we Do_Word_Wrap.  Simple, eh?      }
  1897.   {                                                   }
  1898.   { ------------------------------------------------- }
  1899.  
  1900. begin
  1901.  
  1902.   if CurPos.X > Right_Margin then
  1903.     Do_Word_Wrap (Select_Mode, Center_Cursor);
  1904.  
  1905.  
  1906. end; {Check_For_Word_Wrap}
  1907.  
  1908. { WRAP - Stop. }
  1909.  
  1910.  
  1911.  
  1912. { -------------------------------------------------------------------------- }
  1913.  
  1914.  
  1915.  
  1916. function TEditor.ClipCopy : Boolean;
  1917.  
  1918. begin
  1919.  
  1920.   ClipCopy := False;
  1921.  
  1922.   if (Clipboard <> nil) and (Clipboard <> @Self) then
  1923.   begin
  1924.     ClipCopy := Clipboard^.InsertFrom (@Self);
  1925.     Selecting := False;
  1926.     Update (ufUpdate);
  1927.   end;
  1928.  
  1929.  
  1930. end; { TEditor.ClipCopy }
  1931.  
  1932.  
  1933.  
  1934. { -------------------------------------------------------------------------- }
  1935.  
  1936.  
  1937.  
  1938. procedure TEditor.ClipCut;
  1939.  
  1940. begin
  1941.  
  1942.   if ClipCopy then
  1943.   begin
  1944.  
  1945.     { MARK - Start. }
  1946.  
  1947.     Update_Place_Markers (0,
  1948.                           Self.SelEnd - Self.SelStart,
  1949.                           Self.SelStart,
  1950.                           Self.SelEnd);
  1951.     { MARK - Stop. }
  1952.  
  1953.     DeleteSelect;
  1954.  
  1955.   end;
  1956.  
  1957.  
  1958. end; { TEditor.ClipCut }
  1959.  
  1960.  
  1961.  
  1962. { -------------------------------------------------------------------------- }
  1963.  
  1964.  
  1965.  
  1966. procedure TEditor.ClipPaste;
  1967.  
  1968. begin
  1969.  
  1970.  
  1971.  
  1972.   if (Clipboard <> nil) and (Clipboard <> @Self) then
  1973.     begin
  1974.  
  1975.  
  1976.  
  1977.       { WRAP - Start. }
  1978.  
  1979.       { ---------------------------------------------- }
  1980.       {                                                }
  1981.       { Do not allow paste operations that will exceed }
  1982.       { the Right_Margin when Word_Wrap is active and  }
  1983.       { cursor is at EOL.                              }
  1984.       {                                                }
  1985.       { ---------------------------------------------- }
  1986.  
  1987.  
  1988.       if Word_Wrap and (CurPos.X > Right_Margin) then
  1989.  
  1990.         begin
  1991.           EditorDialog (edPasteNotPossible, nil);
  1992.           Exit;
  1993.         end;
  1994.  
  1995.       { WRAP - Stop. }
  1996.  
  1997.  
  1998.  
  1999.       { MARK - Start. }
  2000.  
  2001.       { ---------------------------------------------------- }
  2002.       {                                                      }
  2003.       { The editor will not copy selected text if the CurPtr }
  2004.       { is not the same value as the SelStart.  However, it  }
  2005.       { does return an InsCount.  This may, or may not, be a }
  2006.       { bug.  We don't want to update the Place_Marker if    }
  2007.       { there's no text copied.                              }
  2008.       {                                                      }
  2009.       { ---------------------------------------------------- }
  2010.  
  2011.       if CurPtr = SelStart then
  2012.  
  2013.         Update_Place_Markers (Clipboard^.SelEnd - Clipboard^.SelStart,
  2014.                               0,
  2015.                               Clipboard^.SelStart,
  2016.                               Clipboard^.SelEnd);
  2017.  
  2018.       { MARK - Stop. }
  2019.  
  2020.       InsertFrom (Clipboard);
  2021.  
  2022.  
  2023.     end;
  2024.  
  2025.  
  2026. end; { TEditor.ClipPaste }
  2027.  
  2028.  
  2029.  
  2030. { -------------------------------------------------------------------------- }
  2031.  
  2032.  
  2033.  
  2034. procedure TEditor.ConvertEvent (var Event : Drivers.TEvent);
  2035.  
  2036. VAR
  2037.  
  2038.   ShiftState : Byte absolute $40:$17;
  2039.   Key        : Word;
  2040.  
  2041.  
  2042. begin
  2043.  
  2044.   if Event.What = evKeyDown then
  2045.   begin
  2046.  
  2047.     if (ShiftState and $03 <> 0)
  2048.                    and (Event.ScanCode >= $47)
  2049.                    and (Event.ScanCode <= $51) then
  2050.       Event.CharCode := #0;
  2051.  
  2052.     Key := Event.KeyCode;
  2053.  
  2054.     if KeyState <> 0 then
  2055.     begin
  2056.       if (Lo (Key) >= $01) and (Lo (Key) <= $1A) then
  2057.         Inc (Key, $40);
  2058.       if (Lo (Key) >= $61) and (Lo (Key) <= $7A) then
  2059.         Dec (Key, $20);
  2060.     end;
  2061.  
  2062.     Key := ScanKeyMap (KeyMap[KeyState], Key);
  2063.     KeyState := 0;
  2064.  
  2065.     if Key <> 0 then
  2066.       if Hi (Key) = $FF then
  2067.         begin
  2068.           KeyState := Lo (Key);
  2069.           ClearEvent (Event);
  2070.         end
  2071.       else
  2072.         begin
  2073.           Event.What := evCommand;
  2074.           Event.Command := Key;
  2075.         end;
  2076.   end;
  2077.  
  2078.  
  2079. end; { TEditor.ConvertEvent }
  2080.  
  2081.  
  2082.  
  2083. { -------------------------------------------------------------------------- }
  2084.  
  2085.  
  2086.  
  2087. function TEditor.CursorVisible : Boolean;
  2088.  
  2089. begin
  2090.  
  2091.   CursorVisible := (CurPos.Y >= Delta.Y) and (CurPos.Y < Delta.Y + Size.Y);
  2092.  
  2093. end; { TEditor.CursorVisible }
  2094.  
  2095.  
  2096.  
  2097. { -------------------------------------------------------------------------- }
  2098.  
  2099.  
  2100.  
  2101. procedure TEditor.DeleteRange (StartPtr, EndPtr : Word; DelSelect : Boolean);
  2102.  
  2103.  
  2104. begin
  2105.  
  2106.   { MARK - Start. }
  2107.  
  2108.   Update_Place_Markers (0, EndPtr - StartPtr, StartPtr, EndPtr);
  2109.  
  2110.   { MARK - Stop. } { This will update Place_Marker for all deletions. }
  2111.                    { EXCEPT the Remove_EOL_Spaces deletion.           }
  2112.  
  2113.   if HasSelection and DelSelect then
  2114.     DeleteSelect
  2115.   else
  2116.     begin
  2117.       SetSelect (CurPtr, EndPtr, True);
  2118.       DeleteSelect;
  2119.       SetSelect (StartPtr, CurPtr, False);
  2120.       DeleteSelect;
  2121.     end;
  2122.  
  2123.  
  2124. end; { TEditor.DeleteRange }
  2125.  
  2126.  
  2127.  
  2128. { -------------------------------------------------------------------------- }
  2129.  
  2130.  
  2131.  
  2132. procedure TEditor.DeleteSelect;
  2133.  
  2134. begin
  2135.  
  2136.   InsertText (nil, 0, False);
  2137.  
  2138. end; { TEditor.DeleteSelect }
  2139.  
  2140.  
  2141.  
  2142. { -------------------------------------------------------------------------- }
  2143.  
  2144.  
  2145. procedure TEditor.DoneBuffer;
  2146.  
  2147. begin
  2148.  
  2149.   if Buffer <> nil then
  2150.     FreeMem (Buffer, BufSize);
  2151.  
  2152. end; { TEditor.DoneBuffer }
  2153.  
  2154.  
  2155.  
  2156. { -------------------------------------------------------------------------- }
  2157.  
  2158.  
  2159.  
  2160. procedure TEditor.DoSearchReplace;
  2161.  
  2162. VAR
  2163.  
  2164.   I : Word;
  2165.   C : Objects.TPoint;
  2166.  
  2167. begin
  2168.   repeat
  2169.  
  2170.     I := Views.cmCancel;
  2171.  
  2172.     if not Search (FindStr, EditorFlags) then
  2173.       begin
  2174.         if EditorFlags and (efReplaceAll + efDoReplace) <>
  2175.             (efReplaceAll + efDoReplace) then
  2176.           EditorDialog (edSearchFailed, nil)
  2177.       end
  2178.     else
  2179.  
  2180.       if EditorFlags and efDoReplace <> 0 then
  2181.       begin
  2182.  
  2183.         I := cmYes;
  2184.         if EditorFlags and efPromptOnReplace <> 0 then
  2185.         begin
  2186.           MakeGlobal (Cursor, C);
  2187.           I := EditorDialog (edReplacePrompt, Pointer (C));
  2188.         end;
  2189.  
  2190.         if I = cmYes then
  2191.           begin
  2192.  
  2193.             { WRAP - Start. }
  2194.  
  2195.             { ---------------------------------------- }
  2196.             {                                          }
  2197.             { If Word_Wrap is active and we are at EOL }
  2198.             { disallow replace by bringing up a dialog }
  2199.             { stating that replace is not possible.    }
  2200.             {                                          }
  2201.             { ---------------------------------------- }
  2202.  
  2203.             if Word_Wrap and
  2204.                ((CurPos.X + (Length (ReplaceStr) - Length (FindStr))) > Right_Margin) then
  2205.               EditorDialog (edReplaceNotPossible, nil)
  2206.             else
  2207.  
  2208.             { WRAP - Stop. }
  2209.  
  2210.               begin
  2211.  
  2212.                 Lock;
  2213.  
  2214.                 { MARK - Start. }
  2215.  
  2216.                 Search_Replace := True;
  2217.  
  2218.                 if length (ReplaceStr) < length (FindStr) then
  2219.                   Update_Place_Markers (0,
  2220.                                         Length (FindStr) - Length (ReplaceStr),
  2221.                                         CurPtr - Length (FindStr) + Length (ReplaceStr),
  2222.                                         CurPtr)
  2223.                 else
  2224.                   if length (ReplaceStr) > length (FindStr) then
  2225.                     Update_Place_Markers (Length (ReplaceStr) - Length (FindStr),
  2226.                                           0,
  2227.                                           CurPtr,
  2228.                                           CurPtr + (Length (ReplaceStr) - Length (FindStr)));
  2229.  
  2230.                 { MARK - Stop. }
  2231.  
  2232.                 InsertText (@ReplaceStr[1], Length (ReplaceStr), False);
  2233.  
  2234.                 { MARK - Start. }
  2235.  
  2236.                 Search_Replace := False;
  2237.  
  2238.                 { MARK - Stop. }
  2239.  
  2240.                 TrackCursor (False);
  2241.                 Unlock;
  2242.  
  2243.              end;
  2244.           end;
  2245.       end;
  2246.  
  2247.   until (I = Views.cmCancel) or (EditorFlags and efReplaceAll = 0);
  2248.  
  2249.  
  2250. end; { TEditor.DoSearchReplace }
  2251.  
  2252.  
  2253.  
  2254. { -------------------------------------------------------------------------- }
  2255.  
  2256.  
  2257.  
  2258. procedure TEditor.DoUpdate;
  2259.  
  2260. begin
  2261.  
  2262.   if UpdateFlags <> 0 then
  2263.   begin
  2264.  
  2265.     SetCursor (CurPos.X - Delta.X, CurPos.Y - Delta.Y);
  2266.  
  2267.     if UpdateFlags and ufView <> 0 then
  2268.       DrawView
  2269.     else
  2270.       if UpdateFlags and ufLine <> 0 then
  2271.         DrawLines (CurPos.Y - Delta.Y, 1, LineStart (CurPtr));
  2272.  
  2273.     if HScrollBar <> nil then
  2274.       HScrollBar^.SetParams (Delta.X, 0, Limit.X - Size.X, Size.X div 2, 1);
  2275.  
  2276.     if VScrollBar <> nil then
  2277.       VScrollBar^.SetParams (Delta.Y, 0, Limit.Y - Size.Y, Size.Y - 1, 1);
  2278.  
  2279.     { STATS - Start. }
  2280.  
  2281.     if Indicator <> nil then
  2282.       Indicator^.SetValue (CurPos, AutoIndent, Modified, Word_Wrap);
  2283.  
  2284.     { STATS - Stop. } { Added AutoIndent and Word_Wrap parameters. }
  2285.  
  2286.     if State and sfActive <> 0 then
  2287.       UpdateCommands;
  2288.  
  2289.     UpdateFlags := 0;
  2290.  
  2291.   end;
  2292.  
  2293.  
  2294. end; { TEditor.DoUpdate }
  2295.  
  2296.  
  2297.  
  2298. { -------------------------------------------------------------------------- }
  2299.  
  2300.  
  2301.  
  2302. { WRAP - Start. }
  2303.  
  2304. function TEditor.Do_Word_Wrap (Select_Mode   : Byte;
  2305.                                Center_Cursor : Boolean) : Boolean;
  2306.  
  2307.  
  2308.  
  2309.   { ---------------------------------------------------------------------- }
  2310.   {                                                                        }
  2311.   { This procedure does the actual wordwrap.  It always assumes the CurPtr }
  2312.   { is at Right_Margin + 1.  It makes several tests for special conditions }
  2313.   { and processes those first.  If they all fail, it does a normal wrap.   }
  2314.   {                                                                        }
  2315.   { ---------------------------------------------------------------------- }
  2316.  
  2317.  
  2318. VAR
  2319.  
  2320.   A : Word;          { Distance between line start and first word on line. }
  2321.   C : Word;          { Current pointer when we come into procedure.        }
  2322.   L : Word;          { BufLen when we come into procedure.                 }
  2323.   P : Word;          { Position of pointer at any given moment.            }
  2324.   S : Word;          { Start of a line.                                    }
  2325.  
  2326. begin
  2327.  
  2328.   Do_Word_Wrap := False;
  2329.   Select_Mode := 0;
  2330.  
  2331.   if BufLen >= (BufSize - 1) then
  2332.     exit;
  2333.  
  2334.   C := CurPtr;
  2335.   L := BufLen;
  2336.   S := LineStart (CurPtr);
  2337.  
  2338.  
  2339.  
  2340.   { -------------------------------------------------------------------- }
  2341.   {                                                                      }
  2342.   { If first character in the line is a space and autoindent mode is on  }
  2343.   { then we check to see if NextWord(S) exceeds the CurPtr.  If it does, }
  2344.   { we set CurPtr as the AutoIndent marker.  If it doesn't, we will set  }
  2345.   { NextWord(S) as the AutoIndent marker.  If neither, we set it to S.   }
  2346.   {                                                                      }
  2347.   { -------------------------------------------------------------------- }
  2348.  
  2349.  
  2350.   if AutoIndent and (Buffer^[S] = ' ') then
  2351.     begin
  2352.       if NextWord (S) > CurPtr then
  2353.         A := CurPtr
  2354.       else
  2355.         A := NextWord (S);
  2356.     end
  2357.   else
  2358.     A := NextWord (S);
  2359.  
  2360.  
  2361.  
  2362.   { --------------------------------------------------------- }
  2363.   {                                                           }
  2364.   { Though NewLine will remove EOL spaces, we do it here too. }
  2365.   { This catches the instance where a user may try to space   }
  2366.   { completely across the line, in which case CurPtr.X = 0.   }
  2367.   {                                                           }
  2368.   { --------------------------------------------------------- }
  2369.  
  2370.  
  2371.   Remove_EOL_Spaces (Select_Mode);
  2372.  
  2373.   if CurPos.X = 0 then
  2374.     begin
  2375.       NewLine (Select_Mode);
  2376.       Do_Word_Wrap := True;
  2377.       Exit;
  2378.     end;
  2379.  
  2380.  
  2381.  
  2382.   { --------------------------------------------------------------------------- }
  2383.   {                                                                             }
  2384.   { At this point we have one of five situations:                               }
  2385.   {                                                                             }
  2386.   { 1)  AutoIndent is on and this line is all spaces before CurPtr.             }
  2387.   { 2)  AutoIndent is off and this line is all spaces before CurPtr.            }
  2388.   { 3)  AutoIndent is on and this line is continuous characters before CurPtr.  }
  2389.   { 4)  AutoIndent is off and this line is continuous characters before CurPtr. }
  2390.   { 5)  This is just a normal line of text.                                     }
  2391.   {                                                                             }
  2392.   { Conditions 1 through 4 have to be taken into account before condition 5.    }
  2393.   {                                                                             }
  2394.   { --------------------------------------------------------------------------- }
  2395.  
  2396.  
  2397.  
  2398.   { ------------------------------------------------------------ }
  2399.   {                                                              }
  2400.   { First, we see if there are all spaces and/or all characters. }
  2401.   { Then we determine which one it really is.  Finally, we take  }
  2402.   { a course of action based on the state of AutoIndent.         }
  2403.   {                                                              }
  2404.   { ------------------------------------------------------------ }
  2405.  
  2406.  
  2407.  
  2408.   if PrevWord (CurPtr) <= S then
  2409.     begin
  2410.  
  2411.       P := CurPtr - 1;
  2412.  
  2413.       while ((Buffer^[P] <> ' ') and (P > S)) do
  2414.         Dec (P);
  2415.  
  2416.  
  2417.  
  2418.       { -------------------------------------------------------------- }
  2419.       {                                                                }
  2420.       { We found NO SPACES.  Conditions 4 and 5 are treated the same.  }
  2421.       { We can NOT do word wrap and put up a dialog box stating such.  }
  2422.       { Delete character just entered so we don't exceed Right_Margin. }
  2423.       {                                                                }
  2424.       { -------------------------------------------------------------- }
  2425.  
  2426.  
  2427.       if P = S then
  2428.         begin
  2429.           EditorDialog (edWrapNotPossible, nil);
  2430.           DeleteRange (PrevChar (CurPtr), CurPtr, True);
  2431.           Exit;
  2432.         end
  2433.       else
  2434.         begin
  2435.  
  2436.  
  2437.  
  2438.           { ------------------------------------------------------- }
  2439.           {                                                         }
  2440.           { There are spaces.  Now find out if they are all spaces. }
  2441.           { If so, see if AutoIndent is on.  If it is, turn it off, }
  2442.           { do a NewLine, and turn it back on.  Otherwise, just do  }
  2443.           { the NewLine.  We go through all of these gyrations for  }
  2444.           { AutoIndent.  Being way out here with a preceding line   }
  2445.           { of spaces and wrapping with AutoIndent on is real dumb! }
  2446.           { However, the user expects something.  The wrap will NOT }
  2447.           { autoindent, but they had no business being here anyway! }
  2448.           {                                                         }
  2449.           { ------------------------------------------------------- }
  2450.  
  2451.  
  2452.           P := CurPtr - 1;
  2453.  
  2454.           while ((Buffer^[P] = ' ') and (P > S)) do
  2455.             Dec (P);
  2456.  
  2457.           if P = S then
  2458.             begin
  2459.  
  2460.               if Autoindent then
  2461.                 begin
  2462.                   AutoIndent := False;
  2463.                   NewLine (Select_Mode);
  2464.                   AutoIndent := True;
  2465.                 end
  2466.               else
  2467.                 NewLine (Select_Mode);
  2468.               end; { AutoIndent }
  2469.  
  2470.             end; { P = S for spaces }
  2471.  
  2472.         end { P = S for no spaces }
  2473.  
  2474.     else { PrevWord (CurPtr) <= S }
  2475.  
  2476.       begin
  2477.  
  2478.  
  2479.         { ---------------------------------------------------------------- }
  2480.         {                                                                  }
  2481.         { Hooray!  We actually had a plain old line of text to wrap!       }
  2482.         { Regardless if we are pushing out a line beyond the Right_Margin, }
  2483.         { or at the end of a line itself, the following will determine     }
  2484.         { exactly where to do the wrap and re-set the cursor accordingly.  }
  2485.         { However, if P = A then we can't wrap.  Show dialog and exit.     }
  2486.         {                                                                  }
  2487.         { ---------------------------------------------------------------- }
  2488.  
  2489.  
  2490.         P := CurPtr;
  2491.  
  2492.         while P - S > Right_Margin do
  2493.           P := PrevWord (P);
  2494.  
  2495.         if (P = A) then
  2496.           begin
  2497.             EditorDialog (edReformNotPossible, nil);
  2498.             SetCurPtr (P, Select_Mode);
  2499.             Exit;
  2500.           end;
  2501.  
  2502.         SetCurPtr (P, Select_Mode);
  2503.         NewLine (Select_Mode);
  2504.  
  2505.     end; { PrevWord (CurPtr <= S }
  2506.  
  2507.  
  2508.  
  2509.   { ---------------------------------------------------------- }
  2510.   {                                                            }
  2511.   { Track the cursor here (it is at CurPos.X = 0) so the view  }
  2512.   { will redraw itself at column 0.  This eliminates having it }
  2513.   { redraw starting at the current cursor and not being able   }
  2514.   { to see text before the cursor.  Of course, we also end up  }
  2515.   { redrawing the view twice, here and back in HandleEvent.    }
  2516.   {                                                            }
  2517.   { Reposition cursor so user can pick up where they left off. }
  2518.   {                                                            }
  2519.   { ---------------------------------------------------------- }
  2520.  
  2521.  
  2522.   TrackCursor (Center_Cursor);
  2523.   SetCurPtr (C - (L - BufLen), Select_Mode);
  2524.  
  2525.   Do_Word_Wrap := True;
  2526.  
  2527.  
  2528. end; { TEditor.Do_Word_Wrap }
  2529.  
  2530. { WRAP - Stop. }
  2531.  
  2532.  
  2533.  
  2534. { -------------------------------------------------------------------------- }
  2535.  
  2536.  
  2537.  
  2538. procedure TEditor.Draw;
  2539.  
  2540. begin
  2541.  
  2542.   if DrawLine <> Delta.Y then
  2543.   begin
  2544.     DrawPtr := LineMove (DrawPtr, Delta.Y - DrawLine);
  2545.     DrawLine := Delta.Y;
  2546.   end;
  2547.  
  2548.   DrawLines (0, Size.Y, DrawPtr);
  2549.  
  2550.  
  2551. end; { TEditor.Draw }
  2552.  
  2553.  
  2554.  
  2555. { -------------------------------------------------------------------------- }
  2556.  
  2557.  
  2558.  
  2559. procedure TEditor.DrawLines (Y, Count : Integer; LinePtr : Word);
  2560.  
  2561. VAR
  2562.  
  2563.   Color : Word;
  2564.   B     : array[0..MaxLineLength - 1] of Word;
  2565.  
  2566. begin
  2567.  
  2568.   Color := GetColor ($0201);
  2569.  
  2570.   while Count > 0 do
  2571.   begin
  2572.     FormatLine (B, LinePtr, Delta.X + Size.X, Color);
  2573.     WriteBuf (0, Y, Size.X, 1, B[Delta.X]);
  2574.     LinePtr := NextLine (LinePtr);
  2575.     Inc (Y);
  2576.     Dec (Count);
  2577.   end;
  2578.  
  2579.  
  2580. end; { TEditor.DrawLines }
  2581.  
  2582.  
  2583.  
  2584. { -------------------------------------------------------------------------- }
  2585.  
  2586.  
  2587.  
  2588. procedure TEditor.Find;
  2589.  
  2590. VAR
  2591.  
  2592.   FindRec : TFindDialogRec;
  2593.  
  2594. begin
  2595.  
  2596.   with FindRec do
  2597.   begin
  2598.  
  2599.     Find := FindStr;
  2600.     Options := EditorFlags;
  2601.  
  2602.     if EditorDialog (edFind, @FindRec) <> Views.cmCancel then
  2603.     begin
  2604.       FindStr := Find;
  2605.       EditorFlags := Options and not efDoReplace;
  2606.       DoSearchReplace;
  2607.     end;
  2608.  
  2609.   end;
  2610.  
  2611.  
  2612. end; { TEditor.Find }
  2613.  
  2614.  
  2615.  
  2616. { -------------------------------------------------------------------------- }
  2617.  
  2618.  
  2619.  
  2620. procedure TEditor.FormatLine (var DrawBuf; LinePtr : Word;
  2621.                                   Width  : Integer;
  2622.                                   Colors : Word); assembler;
  2623.  
  2624. asm
  2625.         PUSH    DS
  2626.         LDS     BX,Self
  2627.         LES     DI,DrawBuf
  2628.         MOV     SI,LinePtr
  2629.         XOR     DX,DX
  2630.         CLD
  2631.         MOV     AH,Colors.Byte[0]
  2632.         MOV     CX,DS:[BX].TEditor.SelStart
  2633.         CALL    @@10
  2634.         MOV     AH,Colors.Byte[1]
  2635.         MOV     CX,DS:[BX].TEditor.CurPtr
  2636.         CALL    @@10
  2637.         ADD     SI,DS:[BX].TEditor.GapLen
  2638.         MOV     CX,DS:[BX].TEditor.SelEnd
  2639.         ADD     CX,DS:[BX].TEditor.GapLen
  2640.         CALL    @@10
  2641.         MOV     AH,Colors.Byte[0]
  2642.         MOV     CX,DS:[BX].TEditor.BufSize
  2643.         CALL    @@10
  2644.         JMP     @@31
  2645. @@10:   SUB     CX,SI
  2646.         JA      @@11
  2647.         RETN
  2648. @@11:   LDS     BX,DS:[BX].TEditor.Buffer
  2649.         ADD     SI,BX
  2650.         MOV     BX,Width
  2651. @@12:   LODSB
  2652.         CMP     AL,' '
  2653.         JB      @@20
  2654. @@13:   STOSW
  2655.         INC     DX
  2656. @@14:   CMP     DX,BX
  2657.         JAE     @@30
  2658.         LOOP    @@12
  2659.         LDS     BX,Self
  2660.         SUB     SI,DS:[BX].TEditor.Buffer.Word[0]
  2661.         RETN
  2662. @@20:   CMP     AL,0DH
  2663.         JE      @@30
  2664.         CMP     AL,09H
  2665.         JNE     @@13
  2666.         MOV     AL,' '
  2667. @@21:   STOSW
  2668.         INC     DX
  2669.         TEST    DL,7
  2670.         JNE     @@21
  2671.         JMP     @@14
  2672. @@30:   POP     CX
  2673. @@31:   MOV     AL,' '
  2674.         MOV     CX,Width
  2675.         SUB     CX,DX
  2676.         JBE     @@32
  2677.         REP     STOSW
  2678. @@32:   POP     DS
  2679.  
  2680.  
  2681. end; {TEditor.FormatLine}
  2682.  
  2683.  
  2684.  
  2685. { -------------------------------------------------------------------------- }
  2686.  
  2687.  
  2688.  
  2689. function TEditor.GetMousePtr (Mouse : Objects.TPoint) : Word;
  2690.  
  2691. begin
  2692.  
  2693.   MakeLocal (Mouse, Mouse);
  2694.   Mouse.X := Max (0, Min (Mouse.X, Size.X - 1));
  2695.   Mouse.Y := Max (0, Min (Mouse.Y, Size.Y - 1));
  2696.  
  2697.   GetMousePtr := CharPtr (LineMove (DrawPtr, Mouse.Y + Delta.Y - DrawLine),
  2698.                           Mouse.X + Delta.X);
  2699.  
  2700.  
  2701. end; { TEditor.GetMousePtr }
  2702.  
  2703.  
  2704.  
  2705. { -------------------------------------------------------------------------- }
  2706.  
  2707.  
  2708.  
  2709. function TEditor.GetPalette : Views.PPalette;
  2710.  
  2711. CONST
  2712.  
  2713.   P : String[Length (CEditor)] = CEditor;
  2714.  
  2715. begin
  2716.  
  2717.   GetPalette := @P;
  2718.  
  2719.  
  2720. end; { TEditor.GetPalette }
  2721.  
  2722.  
  2723.  
  2724. { -------------------------------------------------------------------------- }
  2725.  
  2726.  
  2727.  
  2728. procedure TEditor.HandleEvent (var Event : Drivers.TEvent);
  2729.  
  2730. VAR
  2731.  
  2732.   ShiftState   : Byte absolute $40:$17;
  2733.   CenterCursor : Boolean;
  2734.   SelectMode   : Byte;
  2735.   I            : Integer;
  2736.   D            : Objects.TPoint;
  2737.   Mouse        : Objects.TPoint;
  2738.  
  2739.  
  2740.  
  2741.   { ------------------------------------------------------------------------ }
  2742.  
  2743.  
  2744.  
  2745.   { SCRLBG - Start }
  2746.  
  2747.   { procedure CheckScrollBar (P : PScrollBar; var D : Integer); }
  2748.   function CheckScrollBar (P : PScrollBar; var D : Integer) : Boolean;
  2749.  
  2750.   { SCRLBG - Stop. } { Changed froma procedure to a function. }
  2751.  
  2752.   begin
  2753.  
  2754.     { SCRLBG - Start. }
  2755.  
  2756.     CheckScrollBar := FALSE;
  2757.  
  2758.     { SCRLBG - Stop. } { Set function return to default to FALSE. }
  2759.  
  2760.     if (Event.InfoPtr = P) and (P^.Value <> D) then
  2761.     begin
  2762.       D := P^.Value;
  2763.       Update (ufView);
  2764.  
  2765.       { SCRLBG - Start. }
  2766.  
  2767.       CheckScrollBar := TRUE;
  2768.  
  2769.       { SCRLBG - Stop. } { Set function return to TRUE. }
  2770.  
  2771.     end;
  2772.  
  2773.  
  2774.   end; {CheckScrollBar}
  2775.  
  2776.  
  2777.  
  2778.   { ------------------------------------------------------------------------ }
  2779.  
  2780.  
  2781.  
  2782. begin
  2783.  
  2784.   TView.HandleEvent (Event);
  2785.   ConvertEvent (Event);
  2786.   CenterCursor := not CursorVisible;
  2787.   SelectMode := 0;
  2788.  
  2789.   if Selecting or (ShiftState and $03 <> 0) then
  2790.     SelectMode := smExtend;
  2791.  
  2792.   case Event.What of
  2793.  
  2794.     Drivers.evMouseDown:
  2795.  
  2796.       begin
  2797.         if Event.Double then
  2798.           SelectMode := SelectMode or smDouble;
  2799.  
  2800.         repeat
  2801.           Lock;
  2802.  
  2803.           if Event.What = evMouseAuto then
  2804.           begin
  2805.             MakeLocal (Event.Where, Mouse);
  2806.             D := Delta;
  2807.             if Mouse.X < 0 then
  2808.               Dec (D.X);
  2809.             if Mouse.X >= Size.X then
  2810.               Inc (D.X);
  2811.             if Mouse.Y < 0 then
  2812.               Dec (D.Y);
  2813.             if Mouse.Y >= Size.Y then
  2814.               Inc (D.Y);
  2815.             ScrollTo (D.X, D.Y);
  2816.           end;
  2817.  
  2818.           SetCurPtr (GetMousePtr (Event.Where), SelectMode);
  2819.           SelectMode := SelectMode or smExtend;
  2820.           Unlock;
  2821.  
  2822.         until not MouseEvent (Event, evMouseMove + evMouseAuto);
  2823.  
  2824.       end; { Drivers.evMouseDown }
  2825.  
  2826.     Drivers.evKeyDown:
  2827.  
  2828.       case Event.CharCode of
  2829.  
  2830.         #32..#255:
  2831.  
  2832.           begin
  2833.             Lock;
  2834.  
  2835.             if Overwrite and not HasSelection then
  2836.               if CurPtr <> LineEnd (CurPtr) then
  2837.                 SelEnd := NextChar (CurPtr);
  2838.  
  2839.             InsertText (@Event.CharCode, 1, False);
  2840.  
  2841.             { WRAP - Start. }
  2842.  
  2843.             if Word_Wrap then
  2844.               Check_For_Word_Wrap (SelectMode, CenterCursor);
  2845.  
  2846.             { WRAP - Stop. } { Added code to check for wordwrap. }
  2847.  
  2848.             TrackCursor (CenterCursor);
  2849.             Unlock;
  2850.  
  2851.           end;
  2852.  
  2853.       else
  2854.  
  2855.         Exit;
  2856.  
  2857.       end; { Drivers.evKeyDown }
  2858.  
  2859.     Drivers.evCommand:
  2860.  
  2861.       case Event.Command of
  2862.  
  2863.         cmFind        : Find;
  2864.         cmReplace     : Replace;
  2865.         cmSearchAgain : DoSearchReplace;
  2866.  
  2867.       else
  2868.  
  2869.         begin
  2870.  
  2871.           Lock;
  2872.  
  2873.           case Event.Command of
  2874.  
  2875.             cmCut         : ClipCut;
  2876.             cmCopy        : ClipCopy;
  2877.             cmPaste       : ClipPaste;
  2878.             cmUndo        : Undo;
  2879.             cmClear       : DeleteSelect;
  2880.             cmCharLeft    : SetCurPtr (PrevChar  (CurPtr), SelectMode);
  2881.             cmCharRight   : SetCurPtr (NextChar  (CurPtr), SelectMode);
  2882.             cmWordLeft    : SetCurPtr (PrevWord  (CurPtr), SelectMode);
  2883.             cmWordRight   : SetCurPtr (NextWord  (CurPtr), SelectMode);
  2884.             cmLineStart   : SetCurPtr (LineStart (CurPtr), SelectMode);
  2885.             cmLineEnd     : SetCurPtr (LineEnd   (CurPtr), SelectMode);
  2886.             cmLineUp      : SetCurPtr (LineMove  (CurPtr, -1), SelectMode);
  2887.             cmLineDown    : SetCurPtr (LineMove  (CurPtr, 1),  SelectMode);
  2888.             cmPageUp      : SetCurPtr (LineMove  (CurPtr, - (Size.Y - 1)), SelectMode);
  2889.             cmPageDown    : SetCurPtr (LineMove  (CurPtr, Size.Y - 1), SelectMode);
  2890.             cmTextStart   : SetCurPtr (0, SelectMode);
  2891.             cmTextEnd     : SetCurPtr (BufLen, SelectMode);
  2892.  
  2893.             { WRAP - Start. }
  2894.  
  2895.             cmNewLine     : NewLine (SelectMode);
  2896.  
  2897.             { WRAP - Stop. } { Add new parameter to call. }
  2898.  
  2899.             cmBackSpace   : DeleteRange (PrevChar (CurPtr), CurPtr, True);
  2900.             cmDelChar     : DeleteRange (CurPtr, NextChar (CurPtr), True);
  2901.             cmDelWord     : DeleteRange (CurPtr, NextWord (CurPtr), False);
  2902.             cmDelStart    : DeleteRange (LineStart (CurPtr), CurPtr, False);
  2903.             cmDelEnd      : DeleteRange (CurPtr, LineEnd (CurPtr), False);
  2904.             cmDelLine     : DeleteRange (LineStart (CurPtr), NextLine (CurPtr), False);
  2905.             cmInsMode     : ToggleInsMode;
  2906.             cmStartSelect : StartSelect;
  2907.             cmHideSelect  : HideSelect;
  2908.  
  2909.             { STATS - Start. }
  2910.  
  2911.             cmIndentMode  : begin
  2912.                               AutoIndent := not AutoIndent;
  2913.                               Update (ufStats);
  2914.                             end; { Added provision to update TIndicator if ^QI pressed. }
  2915.  
  2916.             { STATS - Stop. }
  2917.  
  2918.             { CENTER - Start. }
  2919.             { HOMEND - Start. }
  2920.             { INSLIN - Start. }
  2921.             { JLINE  - Start. }
  2922.             { MARK   - Start. }
  2923.             { PRETAB - Start. }
  2924.             { REFDOC - Start. }
  2925.             { REFORM - Start. }
  2926.             { RMSET  - Start. }
  2927.             { SCRLDN - Start. }
  2928.             { SCRLUP - Start. }
  2929.             { SELWRD - Start. }
  2930.             { WRAP   - Start. }
  2931.  
  2932.             cmCenterText  : Center_Text (SelectMode);
  2933.             cmEndPage     : SetCurPtr (LineMove  (CurPtr, Delta.Y - CurPos.Y + Size.Y - 1), SelectMode);
  2934.             cmHomePage    : SetCurPtr (LineMove  (CurPtr, -(CurPos.Y - Delta.Y)), SelectMode);
  2935.             cmInsertLine  : Insert_Line (SelectMode);
  2936.             cmJumpLine    : Jump_To_Line (SelectMode);
  2937.             cmReformDoc   : Reformat_Document (SelectMode, CenterCursor);
  2938.             cmReformPara  : Reformat_Paragraph (SelectMode, CenterCursor);
  2939.             cmRightMargin : Set_Right_Margin;
  2940.             cmScrollDown  : Scroll_Down;
  2941.             cmScrollUp    : Scroll_Up;
  2942.             cmSelectWord  : Select_Word;
  2943.             cmSetTabs     : Set_Tabs;
  2944.             cmTabKey      : Tab_Key (SelectMode);
  2945.  
  2946.             { STATS  - Start. }
  2947.  
  2948.             cmWordWrap    : begin
  2949.                               Word_Wrap := not Word_Wrap;
  2950.                               Update (ufStats);
  2951.                             end; { Added provision to update TIndicator if ^OW pressed. }
  2952.  
  2953.             { STATS  - Stop. }
  2954.  
  2955.             cmSetMark0    : Set_Place_Marker (10);
  2956.             cmSetMark1    : Set_Place_Marker  (1);
  2957.             cmSetMark2    : Set_Place_Marker  (2);
  2958.             cmSetMark3    : Set_Place_Marker  (3);
  2959.             cmSetMark4    : Set_Place_Marker  (4);
  2960.             cmSetMark5    : Set_Place_Marker  (5);
  2961.             cmSetMark6    : Set_Place_Marker  (6);
  2962.             cmSetMark7    : Set_Place_Marker  (7);
  2963.             cmSetMark8    : Set_Place_Marker  (8);
  2964.             cmSetMark9    : Set_Place_Marker  (9);
  2965.  
  2966.             cmJumpMark0   : Jump_Place_Marker (10, SelectMode);
  2967.             cmJumpMark1   : Jump_Place_Marker  (1, SelectMode);
  2968.             cmJumpMark2   : Jump_Place_Marker  (2, SelectMode);
  2969.             cmJumpMark3   : Jump_Place_Marker  (3, SelectMode);
  2970.             cmJumpMark4   : Jump_Place_Marker  (4, SelectMode);
  2971.             cmJumpMark5   : Jump_Place_Marker  (5, SelectMode);
  2972.             cmJumpMark6   : Jump_Place_Marker  (6, SelectMode);
  2973.             cmJumpMark7   : Jump_Place_Marker  (7, SelectMode);
  2974.             cmJumpMark8   : Jump_Place_Marker  (8, SelectMode);
  2975.             cmJumpMark9   : Jump_Place_Marker  (9, SelectMode);
  2976.  
  2977.             { WRAP   - Stop. } { Added cmWordWrap event.                  }
  2978.             { SELWRD - Stop. } { Added cmSelectWord event.                }
  2979.             { SCRLUP - Stop. } { Added cmScrollUp event.                  }
  2980.             { SCRLDN - Stop. } { Added cmScrollDown event.                }
  2981.             { RMSET  - Stop. } { Added cmRightMargin event.               }
  2982.             { REFORM - Stop. } { Added cmReformPara event.                }
  2983.             { REFDOC - Stop. } { Added cmReformDoc event.                 }
  2984.             { PRETAB - Stop. } { Added cmTabKey event.                    }
  2985.             { MARK   - Stop. } { Added cmSetMark# and cmJumpMark# events. }
  2986.             { JLINE  - Stop. } { Added cmJumpLine event.                  }
  2987.             { INSLIN - Stop. } { Added cmInsertLine event.                }
  2988.             { HOMEND - Stop. } { Added cmHomePage and cmEndPage events.   }
  2989.             { CENTER - Stop. { { Added cmCenterText event.                }
  2990.  
  2991.           else
  2992.  
  2993.             Unlock;
  2994.             Exit;
  2995.  
  2996.           end; { Event.Command (Inner) }
  2997.  
  2998.           TrackCursor (CenterCursor);
  2999.  
  3000.           { WRAP - Start. }
  3001.  
  3002.           { ------------------------------------------------------------ }
  3003.           {                                                              }
  3004.           { If the user presses any key except cmNewline or cmBackspace  }
  3005.           { we need to check if the file has been modified yet.  There   }
  3006.           { can be no spaces at the end of a line, or wordwrap doesn't   }
  3007.           { work properly.  We don't want to do this if the file hasn't  }
  3008.           { been modified because the user could be bringing in an ASCII }
  3009.           { file from an editor that allows spaces at the EOL.  If we    }
  3010.           { took them out in that scenario the "M" would appear on the   }
  3011.           { TIndicator line and the user would get upset or confused.    }
  3012.           {                                                              }
  3013.           { ------------------------------------------------------------ }
  3014.  
  3015.  
  3016.           if (Event.Command <> cmNewLine)   and
  3017.              (Event.Command <> cmBackSpace) and
  3018.              (Event.Command <> cmTabKey)    and
  3019.               Modified then
  3020.             Remove_EOL_Spaces (SelectMode);
  3021.  
  3022.           { WRAP - Stop. } { Added code to check for wordwrap, and to  }
  3023.                            { ignore removing EOL spaces for cmNewLine. }
  3024.  
  3025.           Unlock;
  3026.  
  3027.         end; { Event.Command (Outer) }
  3028.  
  3029.       end; { Drivers.evCommand }
  3030.  
  3031.     Drivers.evBroadcast:
  3032.  
  3033.       case Event.Command of
  3034.         cmScrollBarChanged:
  3035.           begin
  3036.  
  3037.             { SCRLBG - Start. }
  3038.  
  3039.             { ------------------------------------------------------------ }
  3040.             {                                                              }
  3041.             { The problem with this bug was that it would clear the event. }
  3042.             { Don't allow the event to be cleared if the sending scrollbar }
  3043.             { is not the scrollbar in question.                            }
  3044.             {                                                              }
  3045.             { ------------------------------------------------------------ }
  3046.  
  3047.             { CheckScrollBar (HScrollBar, Delta.X); }
  3048.             { CheckScrollBar (VScrollBar, Delta.Y); }
  3049.  
  3050.             if NOT (CheckScrollBar (HScrollBar, Delta.X)
  3051.                 OR  CheckScrollBar (VScrollBar, Delta.Y)) then
  3052.               Exit;
  3053.  
  3054.           end;
  3055.       else
  3056.  
  3057.         Exit;
  3058.  
  3059.       end; { Drivers.evBroadcast }
  3060.  
  3061.   end;
  3062.  
  3063.   ClearEvent (Event);
  3064.  
  3065.  
  3066. end; { TEditor.HandleEvent }
  3067.  
  3068.  
  3069.  
  3070. { -------------------------------------------------------------------------- }
  3071.  
  3072.  
  3073.  
  3074. function TEditor.HasSelection : Boolean;
  3075.  
  3076. begin
  3077.  
  3078.   HasSelection := SelStart <> SelEnd;
  3079.  
  3080.  
  3081. end; { TEditor.HasSelection }
  3082.  
  3083.  
  3084.  
  3085. { -------------------------------------------------------------------------- }
  3086.  
  3087.  
  3088.  
  3089. procedure TEditor.HideSelect;
  3090.  
  3091. begin
  3092.  
  3093.   Selecting := False;
  3094.   SetSelect (CurPtr, CurPtr, False);
  3095.  
  3096.  
  3097. end; { TEditor.HideSelect }
  3098.  
  3099.  
  3100.  
  3101. { -------------------------------------------------------------------------- }
  3102.  
  3103.  
  3104.  
  3105. procedure TEditor.InitBuffer;
  3106.  
  3107. begin
  3108.  
  3109.   Buffer := MemAlloc (BufSize);
  3110.  
  3111.  
  3112. end; { TEditor.InitBuffer }
  3113.  
  3114.  
  3115.  
  3116. { -------------------------------------------------------------------------- }
  3117.  
  3118.  
  3119.  
  3120. function TEditor.InsertBuffer (var P : PEditBuffer;
  3121.                                Offset,    Length     : Word;
  3122.                                AllowUndo, SelectText : Boolean) : Boolean;
  3123.  
  3124. VAR
  3125.  
  3126.   SelLen   : Word;
  3127.   DelLen   : Word;
  3128.   SelLines : Word;
  3129.   Lines    : Word;
  3130.   NewSize  : Longint;
  3131.  
  3132. begin
  3133.  
  3134.   InsertBuffer := True;
  3135.   Selecting := False;
  3136.  
  3137.   SelLen := SelEnd - SelStart;
  3138.  
  3139.   if (SelLen = 0) and (Length = 0) then
  3140.     Exit;
  3141.  
  3142.   DelLen := 0;
  3143.  
  3144.   if AllowUndo then
  3145.     if CurPtr = SelStart then
  3146.       DelLen := SelLen
  3147.     else
  3148.       if SelLen > InsCount then
  3149.         DelLen := SelLen - InsCount;
  3150.  
  3151.   NewSize := Longint (BufLen + DelCount - SelLen + DelLen) + Length;
  3152.  
  3153.   if NewSize > BufLen + DelCount then
  3154.     if (NewSize > $FFF0) or not SetBufSize (NewSize) then
  3155.       begin
  3156.         EditorDialog (edOutOfMemory, nil);
  3157.         InsertBuffer := False;
  3158.         Exit;
  3159.       end;
  3160.  
  3161.   SelLines := CountLines (Buffer^[BufPtr (SelStart)], SelLen);
  3162.  
  3163.   if CurPtr = SelEnd then
  3164.   begin
  3165.  
  3166.     if AllowUndo then
  3167.     begin
  3168.       if DelLen > 0 then
  3169.         Move (Buffer^[SelStart], Buffer^[CurPtr + GapLen - DelCount - DelLen], DelLen);
  3170.       Dec (InsCount, SelLen - DelLen);
  3171.     end;
  3172.  
  3173.     CurPtr := SelStart;
  3174.     Dec (CurPos.Y, SelLines);
  3175.  
  3176.   end;
  3177.  
  3178.   if Delta.Y > CurPos.Y then
  3179.     begin
  3180.       Dec (Delta.Y, SelLines);
  3181.       if Delta.Y < CurPos.Y then
  3182.         Delta.Y := CurPos.Y;
  3183.     end;
  3184.  
  3185.   if Length > 0 then
  3186.     Move (P^[Offset], Buffer^[CurPtr], Length);
  3187.  
  3188.   Lines := CountLines (Buffer^[CurPtr], Length);
  3189.  
  3190.   Inc (CurPtr, Length);
  3191.   Inc (CurPos.Y, Lines);
  3192.  
  3193.   DrawLine := CurPos.Y;
  3194.   DrawPtr := LineStart (CurPtr);
  3195.  
  3196.   CurPos.X := CharPos (DrawPtr, CurPtr);
  3197.  
  3198.   if not SelectText then
  3199.     SelStart := CurPtr;
  3200.  
  3201.   SelEnd := CurPtr;
  3202.  
  3203.   Inc (BufLen, Length - SelLen);
  3204.   Dec (GapLen, Length - SelLen);
  3205.  
  3206.   if AllowUndo then
  3207.     begin
  3208.       Inc (DelCount, DelLen);
  3209.       Inc (InsCount, Length);
  3210.     end;
  3211.  
  3212.   Inc (Limit.Y, Lines - SelLines);
  3213.   Delta.Y := Max (0, Min (Delta.Y, Limit.Y - Size.Y));
  3214.  
  3215.   if not IsClipboard then
  3216.     Modified := True;
  3217.  
  3218.   SetBufSize (BufLen + DelCount);
  3219.  
  3220.   if (SelLines = 0) and (Lines = 0) then
  3221.     Update (ufLine)
  3222.   else
  3223.     Update (ufView);
  3224.  
  3225.  
  3226. end; { TEditor.InsertBuffer }
  3227.  
  3228.  
  3229.  
  3230. { -------------------------------------------------------------------------- }
  3231.  
  3232.  
  3233.  
  3234. function TEditor.InsertFrom (Editor : PEditor) : Boolean;
  3235.  
  3236. begin
  3237.  
  3238.   InsertFrom := InsertBuffer (Editor^.Buffer,
  3239.     Editor^.BufPtr (Editor^.SelStart),
  3240.     Editor^.SelEnd - Editor^.SelStart, CanUndo, IsClipboard);
  3241.  
  3242.  
  3243. end; { TEditor.InsertFrom }
  3244.  
  3245.  
  3246.  
  3247. { -------------------------------------------------------------------------- }
  3248.  
  3249.  
  3250.  
  3251. { INSLIN - Start. }
  3252.  
  3253. procedure TEditor.Insert_Line (Select_Mode : Byte);
  3254.  
  3255.  
  3256.   { --------------------------------------------------------------- }
  3257.   {                                                                 }
  3258.   { This procedure inserts a newline at the current cursor position }
  3259.   { if a ^N is pressed.  Unlike cmNewLine, the cursor will return   }
  3260.   { to its original position.  If the cursor was at the end of a    }
  3261.   { line, and its spaces were removed, the cursor returns to the    }
  3262.   { end of the line instead.                                        }
  3263.   {                                                                 }
  3264.   { --------------------------------------------------------------- }
  3265.  
  3266.  
  3267.  
  3268. begin
  3269.  
  3270.   NewLine (Select_Mode);
  3271.   SetCurPtr (LineEnd (LineMove (CurPtr, -1)), Select_Mode);
  3272.  
  3273.  
  3274. end; { TEditor.Insert_Line }
  3275.  
  3276. { INSLIN - Stop. }
  3277.  
  3278.  
  3279.  
  3280. { -------------------------------------------------------------------------- }
  3281.  
  3282.  
  3283.  
  3284. function TEditor.InsertText (Text       : Pointer;
  3285.                              Length     : Word;
  3286.                              SelectText : Boolean) : Boolean;
  3287.  
  3288. begin
  3289.  
  3290.   { MARK - Start. }
  3291.  
  3292.   if (Text <> NIL) and not Search_Replace then
  3293.     Update_Place_Markers (Length, 0, Self.SelStart, Self.SelEnd);
  3294.  
  3295.   { MARK - Stop } { This will update Place_Marker ONLY if we are inserting text.}
  3296.                   { ClipPaste and deletions of any sort are handled elsewhere.  }
  3297.  
  3298.   InsertText := InsertBuffer (PEditBuffer (Text),
  3299.                 0, Length, CanUndo, SelectText);
  3300.  
  3301.  
  3302. end; { TEditor.InsertText }
  3303.  
  3304.  
  3305.  
  3306. { -------------------------------------------------------------------------- }
  3307.  
  3308.  
  3309.  
  3310. function TEditor.IsClipboard : Boolean;
  3311.  
  3312. begin
  3313.  
  3314.   IsClipboard := Clipboard = @Self;
  3315.  
  3316.  
  3317. end; { TEditor.IsClipboard }
  3318.  
  3319.  
  3320.  
  3321. { -------------------------------------------------------------------------- }
  3322.  
  3323.  
  3324.  
  3325. { MARK - Start. }
  3326.  
  3327. procedure TEditor.Jump_Place_Marker (Element : Byte; Select_Mode : Byte);
  3328.  
  3329.  
  3330.   { ---------------------------------------------------------- }
  3331.   {                                                            }
  3332.   { This procedure jumps to a place marker if ^Q# is pressed.  }
  3333.   { We don't go anywhere if Place_Marker[Element] is not zero. }
  3334.   {                                                            }
  3335.   { ---------------------------------------------------------- }
  3336.  
  3337.  
  3338. begin
  3339.  
  3340.   if (not IsClipboard) and (Place_Marker[Element] <> 0) then
  3341.     SetCurPtr (Place_Marker[Element], Select_Mode);
  3342.  
  3343.  
  3344. end; { TEditor.Jump_Place_Marker }
  3345.  
  3346. { MARK - Stop. }
  3347.  
  3348.  
  3349.  
  3350. { -------------------------------------------------------------------------- }
  3351.  
  3352.  
  3353.  
  3354. { JLINE - Start. }
  3355.  
  3356. procedure TEditor.Jump_To_Line (Select_Mode : Byte);
  3357.  
  3358.  
  3359.   { ------------------------------------------------ }
  3360.   {                                                  }
  3361.   { This function brings up a dialog box that allows }
  3362.   { the user to select a line number to jump to.     }
  3363.   {                                                  }
  3364.   { ------------------------------------------------ }
  3365.  
  3366.  
  3367. VAR
  3368.  
  3369.   Code       : Integer;         { Used for Val conversion.      }
  3370.   Temp_Value : Integer;         { Holds converted dialog value. }
  3371.  
  3372. begin
  3373.  
  3374.  
  3375.   if EditorDialog (edJumpToLine, @Line_Number) <> Views.cmCancel then
  3376.     begin
  3377.  
  3378.  
  3379.  
  3380.       { ---------------------------------------------- }
  3381.       {                                                }
  3382.       { Convert the Line_Number string to an interger. }
  3383.       { Put it into Temp_Value.  If the number is not  }
  3384.       { in the range 1..9999 abort.  If the number is  }
  3385.       { our current Y position, abort.  Otherwise,     }
  3386.       { go to top of document, and jump to the line.   }
  3387.       { There are faster methods.  This one's easy.    }
  3388.       { Note that CurPos.Y is always 1 less than what  }
  3389.       { the TIndicator line says.                      }
  3390.       {                                                }
  3391.       { ---------------------------------------------- }
  3392.  
  3393.  
  3394.       val (Line_Number, Temp_Value, Code);
  3395.  
  3396.       if (Temp_Value < 1) or (Temp_Value > 9999) then
  3397.         Exit;
  3398.  
  3399.       if Temp_Value = CurPos.Y + 1 then
  3400.         Exit;
  3401.  
  3402.       SetCurPtr (0, Select_Mode);
  3403.       SetCurPtr (LineMove (CurPtr, Temp_Value - 1), Select_Mode);
  3404.  
  3405.     end;
  3406.  
  3407.  
  3408. end; {TEditor.Jump_To_Line}
  3409.  
  3410. { JLINE - Stop. }
  3411.  
  3412.  
  3413.  
  3414. { -------------------------------------------------------------------------- }
  3415.  
  3416.  
  3417.  
  3418. function TEditor.LineEnd (P : Word) : Word; assembler;
  3419.  
  3420. asm
  3421.         PUSH    DS
  3422.         LDS     SI,Self
  3423.         LES     BX,DS:[SI].TEditor.Buffer
  3424.         MOV     DI,P
  3425.         MOV     AL,0DH
  3426.         CLD
  3427.         MOV     CX,DS:[SI].TEditor.CurPtr
  3428.         SUB     CX,DI
  3429.         JBE     @@1
  3430.         ADD     DI,BX
  3431.         REPNE   SCASB
  3432.         JE      @@2
  3433.         MOV     DI,DS:[SI].TEditor.CurPtr
  3434. @@1:    MOV     CX,DS:[SI].TEditor.BufLen
  3435.         SUB     CX,DI
  3436.         JCXZ    @@4
  3437.         ADD     BX,DS:[SI].TEditor.GapLen
  3438.         ADD     DI,BX
  3439.         REPNE   SCASB
  3440.         JNE     @@3
  3441. @@2:    DEC     DI
  3442. @@3:    SUB     DI,BX
  3443. @@4:    MOV     AX,DI
  3444.         POP     DS
  3445.  
  3446.  
  3447. end; { TEditor.LineEnd }
  3448.  
  3449.  
  3450.  
  3451. { -------------------------------------------------------------------------- }
  3452.  
  3453.  
  3454.  
  3455. function TEditor.LineMove (P : Word; Count : Integer) : Word;
  3456.  
  3457. VAR
  3458.  
  3459.   Pos : Integer;
  3460.   I   : Word;
  3461.  
  3462. begin
  3463.  
  3464.   I := P;
  3465.   P := LineStart (P);
  3466.   Pos := CharPos (P, I);
  3467.  
  3468.   while Count <> 0 do
  3469.   begin
  3470.     I := P;
  3471.     if Count < 0 then
  3472.       begin
  3473.         P := PrevLine (P);
  3474.         Inc (Count);
  3475.       end
  3476.     else
  3477.       begin
  3478.         P := NextLine (P);
  3479.         Dec (Count);
  3480.       end;
  3481.   end;
  3482.  
  3483.   if P <> I then
  3484.     P := CharPtr (P, Pos);
  3485.  
  3486.   LineMove := P;
  3487.  
  3488.  
  3489. end; { TEditor.LineMove }
  3490.  
  3491.  
  3492.  
  3493. { -------------------------------------------------------------------------- }
  3494.  
  3495.  
  3496.  
  3497. function TEditor.LineStart (P : Word) : Word; assembler;
  3498.  
  3499. asm
  3500.         PUSH    DS
  3501.         LDS     SI,Self
  3502.         LES     BX,DS:[SI].TEditor.Buffer
  3503.         MOV     DI,P
  3504.         MOV     AL,0DH
  3505.         STD
  3506.         MOV     CX,DI
  3507.         SUB     CX,DS:[SI].TEditor.CurPtr
  3508.         JBE     @@1
  3509.         ADD     BX,DS:[SI].TEditor.GapLen
  3510.         ADD     DI,BX
  3511.         DEC     DI
  3512.         REPNE   SCASB
  3513.         JE      @@2
  3514.         SUB     BX,DS:[SI].TEditor.GapLen
  3515.         MOV     DI,DS:[SI].TEditor.CurPtr
  3516. @@1:    MOV     CX,DI
  3517.         JCXZ    @@4
  3518.         ADD     DI,BX
  3519.         DEC     DI
  3520.         REPNE   SCASB
  3521.         JNE     @@3
  3522. @@2:    INC     DI
  3523.         INC     DI
  3524.         SUB     DI,BX
  3525.         CMP     DI,DS:[SI].TEditor.CurPtr
  3526.         JE      @@4
  3527.         CMP     DI,DS:[SI].TEditor.BufLen
  3528.         JE      @@4
  3529.         CMP     ES:[BX+DI].Byte,0AH
  3530.         JNE     @@4
  3531.         INC     DI
  3532.         JMP     @@4
  3533. @@3:    XOR     DI,DI
  3534. @@4:    MOV     AX,DI
  3535.         POP     DS
  3536.  
  3537.  
  3538. end; { TEditor.LineStart }
  3539.  
  3540.  
  3541.  
  3542. { -------------------------------------------------------------------------- }
  3543.  
  3544.  
  3545.  
  3546. procedure TEditor.Lock;
  3547.  
  3548. begin
  3549.  
  3550.   Inc (LockCount);
  3551.  
  3552.  
  3553. end; { TEditor.Lock }
  3554.  
  3555.  
  3556.  
  3557. { -------------------------------------------------------------------------- }
  3558.  
  3559.  
  3560.  
  3561. { WRAP - Start. }
  3562.  
  3563. function TEditor.NewLine (Select_Mode : Byte) : Boolean;
  3564.  
  3565.  
  3566.  
  3567. CONST
  3568.  
  3569.   CrLf : array[1..2] of Char = #13#10;
  3570.  
  3571. VAR
  3572.  
  3573.   I : Word;          { Used to track spaces for AutoIndent.                 }
  3574.   P : Word;          { Position of Cursor when we arrive and after Newline. }
  3575.  
  3576. begin
  3577.  
  3578.   P := LineStart (CurPtr);
  3579.   I := P;
  3580.  
  3581.  
  3582.  
  3583.   { -------------------------------------------------------- }
  3584.   {                                                          }
  3585.   { The first thing we do is remove any End Of Line spaces.  }
  3586.   { Then we check to see how many spaces are on beginning    }
  3587.   { of a line.   We need this check to add them after CR/LF  }
  3588.   { if AutoIndenting.  Last of all we insert spaces required }
  3589.   { for the AutoIndenting, if it was on.                     }
  3590.   {                                                          }
  3591.   { -------------------------------------------------------- }
  3592.  
  3593.  
  3594.   Remove_EOL_Spaces (Select_Mode);
  3595.  
  3596.   while (I < CurPtr) and ((Buffer^[I] = ' ') or (Buffer^[I] = #9)) do
  3597.      Inc (I);
  3598.  
  3599.   if InsertText (@CrLf, 2, False) = FALSE then
  3600.     exit;
  3601.  
  3602.   if AutoIndent then
  3603.     InsertText (@Buffer^[P], I - P, False);
  3604.  
  3605.  
  3606.  
  3607.   { ------------------------------------------------ }
  3608.   {                                                  }
  3609.   { Remember where the CurPtr is at this moment.     }
  3610.   { Remember the length of the buffer at the moment. }
  3611.   { Go to the previous line and remove EOL spaces.   }
  3612.   { Once removed, re-set the cursor to where we were }
  3613.   { minus any spaces that might have been removed.   }
  3614.   {                                                  }
  3615.   { ------------------------------------------------ }
  3616.  
  3617.  
  3618.   I := BufLen;
  3619.   P := CurPtr;
  3620.  
  3621.   SetCurPtr (LineMove (CurPtr, - 1), Select_Mode);
  3622.   Remove_EOL_Spaces (Select_Mode);
  3623.  
  3624.   if I - BufLen <> 0 then
  3625.     SetCurPtr (P - (I - BufLen), Select_Mode)
  3626.   else
  3627.     SetCurPtr (P, Select_Mode);
  3628.  
  3629.  
  3630. end; { TEditor.NewLine }
  3631.  
  3632. { WRAP - Stop. } { Added new parameter and new code to support wordwrap. }
  3633.  
  3634.  
  3635.  
  3636. { -------------------------------------------------------------------------- }
  3637.  
  3638.  
  3639.  
  3640. function TEditor.NextChar (P : Word) : Word; assembler;
  3641.  
  3642. asm
  3643.         PUSH    DS
  3644.         LDS     SI,Self
  3645.         MOV     DI,P
  3646.         CMP     DI,DS:[SI].TEditor.BufLen
  3647.         JE      @@2
  3648.         INC     DI
  3649.         CMP     DI,DS:[SI].TEditor.BufLen
  3650.         JE      @@2
  3651.         LES     BX,DS:[SI].TEditor.Buffer
  3652.         CMP     DI,DS:[SI].TEditor.CurPtr
  3653.         JB      @@1
  3654.         ADD     BX,DS:[SI].TEditor.GapLen
  3655. @@1:    CMP     ES:[BX+DI-1].Word,0A0DH
  3656.         JNE     @@2
  3657.         INC     DI
  3658. @@2:    MOV     AX,DI
  3659.         POP     DS
  3660.  
  3661.  
  3662. end; { TEditor.NextChar }
  3663.  
  3664.  
  3665.  
  3666. { -------------------------------------------------------------------------- }
  3667.  
  3668.  
  3669.  
  3670. function TEditor.NextLine (P : Word) : Word;
  3671.  
  3672. begin
  3673.  
  3674.   NextLine := NextChar (LineEnd (P));
  3675.  
  3676.  
  3677. end; { TEditor.NextLine }
  3678.  
  3679.  
  3680.  
  3681. { -------------------------------------------------------------------------- }
  3682.  
  3683.  
  3684.  
  3685. function TEditor.NextWord (P : Word) : Word;
  3686.  
  3687.  
  3688. begin
  3689.  
  3690.   while (P < BufLen) and (BufChar (P) in WordChars) do
  3691.     P := NextChar (P);
  3692.  
  3693.   while (P < BufLen) and not (BufChar (P) in WordChars) do
  3694.     P := NextChar (P);
  3695.  
  3696.   NextWord := P;
  3697.  
  3698.  
  3699. end; { TEditor.NextWord }
  3700.  
  3701.  
  3702.  
  3703. { -------------------------------------------------------------------------- }
  3704.  
  3705.  
  3706.  
  3707. function TEditor.PrevChar (P : Word) : Word; assembler;
  3708.  
  3709. asm
  3710.         PUSH    DS
  3711.         LDS     SI,Self
  3712.         MOV     DI,P
  3713.         OR      DI,DI
  3714.         JE      @@2
  3715.         DEC     DI
  3716.         JE      @@2
  3717.         LES     BX,DS:[SI].TEditor.Buffer
  3718.         CMP     DI,DS:[SI].TEditor.CurPtr
  3719.         JB      @@1
  3720.         ADD     BX,DS:[SI].TEditor.GapLen
  3721. @@1:    CMP     ES:[BX+DI-1].Word,0A0DH
  3722.         JNE     @@2
  3723.         DEC     DI
  3724. @@2:    MOV     AX,DI
  3725.         POP     DS
  3726.  
  3727.  
  3728. end; { TEditor.PrevChar }
  3729.  
  3730.  
  3731.  
  3732. { -------------------------------------------------------------------------- }
  3733.  
  3734.  
  3735.  
  3736. function TEditor.PrevLine (P : Word) : Word;
  3737.  
  3738. begin
  3739.  
  3740.   PrevLine := LineStart (PrevChar (P));
  3741.  
  3742.  
  3743. end; { TEditor.PrevLine }
  3744.  
  3745.  
  3746.  
  3747. { -------------------------------------------------------------------------- }
  3748.  
  3749.  
  3750.  
  3751. function TEditor.PrevWord (P : Word) : Word;
  3752.  
  3753. begin
  3754.  
  3755.   while (P > 0) and not (BufChar (PrevChar (P)) in WordChars) do
  3756.     P := PrevChar (P);
  3757.  
  3758.   while (P > 0) and (BufChar (PrevChar (P)) in WordChars) do
  3759.     P := PrevChar (P);
  3760.  
  3761.   PrevWord := P;
  3762.  
  3763.  
  3764. end; { TEditor.PrevWord }
  3765.  
  3766.  
  3767.  
  3768. { -------------------------------------------------------------------------- }
  3769.  
  3770.  
  3771.  
  3772. { REFDOC - Start. }
  3773.  
  3774. procedure TEditor.Reformat_Document (Select_Mode : Byte; Center_Cursor : Boolean);
  3775.  
  3776.  
  3777.   { -------------------------------------------------------------------- }
  3778.   {                                                                      }
  3779.   { This procedure will do a reformat of the entire document, or just    }
  3780.   { from the current line to the end of the document, if ^QU is pressed. }
  3781.   { It simply brings up the correct dialog box, and then calls the       }
  3782.   { TEditor.Reformat_Paragraph procedure to do the actual reformatting.  }
  3783.   {                                                                      }
  3784.   { -------------------------------------------------------------------- }
  3785.  
  3786.  
  3787. CONST
  3788.  
  3789.   efCurrentLine   = $0000;  { Radio button #1 selection for dialog box.  }
  3790.   efWholeDocument = $0001;  { Radio button #2 selection for dialog box.  }
  3791.  
  3792. VAR
  3793.  
  3794.   Reformat_Options : Word;  { Holds the dialog options for reformatting. }
  3795.  
  3796.  
  3797. begin
  3798.  
  3799.  
  3800.  
  3801.   { ----------------------------------------------------------------- }
  3802.   {                                                                   }
  3803.   { Check if Word_Wrap is toggled on.  If NOT on, check if programmer }
  3804.   { allows reformatting of document and if not show user dialog that  }
  3805.   { says reformatting is not permissable.                             }
  3806.   {                                                                   }
  3807.   { ----------------------------------------------------------------- }
  3808.  
  3809.  
  3810.   if not Word_Wrap then
  3811.     begin
  3812.       if not Allow_Reformat then
  3813.         begin
  3814.           EditorDialog (edReformatNotAllowed, nil);
  3815.           Exit;
  3816.         end;
  3817.       Word_Wrap := True;
  3818.       Update (ufStats);
  3819.     end;
  3820.  
  3821.  
  3822.  
  3823.   { ------------------------------------------------------------- }
  3824.   {                                                               }
  3825.   { Default radio button option to 1st one.  Bring up dialog box. }
  3826.   {                                                               }
  3827.   { ------------------------------------------------------------- }
  3828.  
  3829.  
  3830.   Reformat_Options := efCurrentLine;
  3831.  
  3832.   if EditorDialog (edReformatDocument, @Reformat_Options) <> Views.cmCancel then
  3833.     begin
  3834.  
  3835.  
  3836.  
  3837.       { ----------------------------------------------------------- }
  3838.       {                                                             }
  3839.       { If the option to reformat the whole document was selected   }
  3840.       { we need to go back to start of document.  Otherwise we stay }
  3841.       { on the current line.  Call Reformat_Paragraph until we get  }
  3842.       { to the end of the document to do the reformatting.          }
  3843.       {                                                             }
  3844.       { ----------------------------------------------------------- }
  3845.  
  3846.  
  3847.       if Reformat_Options and efWholeDocument <> 0 then
  3848.         SetCurPtr (0, Select_Mode);
  3849.  
  3850.       Unlock;
  3851.  
  3852.       repeat
  3853.         Lock;
  3854.  
  3855.         if NOT Reformat_Paragraph (Select_Mode, Center_Cursor) then
  3856.           Exit;
  3857.  
  3858.         TrackCursor (False);
  3859.         Unlock;
  3860.       until CurPtr = BufLen;
  3861.  
  3862.     end;
  3863.  
  3864.  
  3865. end; { TEditor.Reformat_Document }
  3866.  
  3867. { REFDOC - Stop. }
  3868.  
  3869.  
  3870.  
  3871. { -------------------------------------------------------------------------- }
  3872.  
  3873.  
  3874.  
  3875. { REFORM - Start. }
  3876.  
  3877. function TEditor.Reformat_Paragraph (Select_Mode   : Byte;
  3878.                                      Center_Cursor : Boolean) : Boolean;
  3879.  
  3880.  
  3881.   { ------------------------------------------------------------------------- }
  3882.   {                                                                           }
  3883.   { This procedure will do a reformat of the current paragraph if ^B pressed. }
  3884.   { The feature works regardless if wordrap is on or off.  It also supports   }
  3885.   { the AutoIndent feature.  Reformat is not possible if the CurPos exceeds   }
  3886.   { the Right_Margin.  Right_Margin is where the EOL is considered to be.     }
  3887.   {                                                                           }
  3888.   { ------------------------------------------------------------------------- }
  3889.  
  3890.  
  3891. CONST
  3892.  
  3893.   Space : array [1..2] of Char = #32#32;
  3894.  
  3895. VAR
  3896.  
  3897.   C : Word;  { Position of CurPtr when we come into procedure. }
  3898.   E : Word;  { End of a line.                                  }
  3899.   S : Word;  { Start of a line.                                }
  3900.  
  3901. begin
  3902.  
  3903.   Reformat_Paragraph := False;
  3904.  
  3905.  
  3906.  
  3907.   { ----------------------------------------------------------------- }
  3908.   {                                                                   }
  3909.   { Check if Word_Wrap is toggled on.  If NOT on, check if programmer }
  3910.   { allows reformatting of paragraph and if not show user dialog that }
  3911.   { says reformatting is not permissable.                             }
  3912.   {                                                                   }
  3913.   { ----------------------------------------------------------------- }
  3914.  
  3915.  
  3916.   if not Word_Wrap then
  3917.     begin
  3918.       if not Allow_Reformat then
  3919.         begin
  3920.           EditorDialog (edReformatNotAllowed, nil);
  3921.           Exit;
  3922.         end;
  3923.       Word_Wrap := True;
  3924.       Update (ufStats);
  3925.     end;
  3926.  
  3927.  
  3928.  
  3929.   C := CurPtr;
  3930.   E := LineEnd (CurPtr);
  3931.   S := LineStart (CurPtr);
  3932.  
  3933.  
  3934.  
  3935.   { ---------------------------------------------------- }
  3936.   {                                                      }
  3937.   { Reformat possible only if current line is NOT blank! }
  3938.   {                                                      }
  3939.   { ---------------------------------------------------- }
  3940.  
  3941.  
  3942.   if E <> S then
  3943.     begin
  3944.  
  3945.  
  3946.  
  3947.       { ------------------------------------------ }
  3948.       {                                            }
  3949.       { Reformat is NOT possible if the first word }
  3950.       { on the line is beyond the Right_Margin.    }
  3951.       {                                            }
  3952.       { ------------------------------------------ }
  3953.  
  3954.  
  3955.       S := LineStart (CurPtr);
  3956.  
  3957.       if NextWord (S) - S >= Right_Margin - 1 then
  3958.         begin
  3959.           EditorDialog (edReformNotPossible, nil);
  3960.           Exit;
  3961.         end;
  3962.  
  3963.  
  3964.  
  3965.       { ----------------------------------------------- }
  3966.       {                                                 }
  3967.       { First objective is to find the first blank line }
  3968.       { after this paragraph so we know when to stop.   }
  3969.       { That could be the end of the document.          }
  3970.       {                                                 }
  3971.       { ----------------------------------------------- }
  3972.  
  3973.  
  3974.       Repeat
  3975.         SetCurPtr (LineMove (CurPtr, 1), Select_Mode);
  3976.         E := LineEnd (CurPtr);
  3977.         S := LineStart (CurPtr);
  3978.         BlankLine := E;
  3979.       until ((CurPtr = BufLen) or (E = S));
  3980.  
  3981.       SetCurPtr (C, Select_Mode);
  3982.  
  3983.       repeat
  3984.  
  3985.  
  3986.  
  3987.         { ------------------------------------------------ }
  3988.         {                                                  }
  3989.         { Set CurPtr to LineEnd and remove the EOL spaces. }
  3990.         { Pull up the next line and remove its EOL space.  }
  3991.         { First make sure the next line is not BlankLine!  }
  3992.         { Insert spaces as required between the two lines. }
  3993.         {                                                  }
  3994.         { ------------------------------------------------ }
  3995.  
  3996.  
  3997.         SetCurPtr (LineEnd (CurPtr), Select_Mode);
  3998.         Remove_EOL_Spaces (Select_Mode);
  3999.         if CurPtr <> Blankline - 2 then
  4000.           DeleteRange (CurPtr, Nextword (CurPtr), True);
  4001.         Remove_EOL_Spaces (Select_Mode);
  4002.  
  4003.         case Buffer^[CurPtr-1] of
  4004.           '!' : InsertText (@Space, 2, False);
  4005.           '.' : InsertText (@Space, 2, False);
  4006.           ':' : InsertText (@Space, 2, False);
  4007.           '?' : InsertText (@Space, 2, False);
  4008.         else
  4009.           InsertText (@Space, 1, False);
  4010.         end;
  4011.  
  4012.  
  4013.  
  4014.         { --------------------------------------------------------- }
  4015.         {                                                           }
  4016.         { Reset CurPtr to EOL.  While line length is > Right_Margin }
  4017.         { go Do_Word_Wrap.  If wordrap failed, exit routine.        }
  4018.         {                                                           }
  4019.         { --------------------------------------------------------- }
  4020.  
  4021.  
  4022.         SetCurPtr (LineEnd (CurPtr), Select_Mode);
  4023.  
  4024.         while LineEnd (CurPtr) - LineStart (CurPtr) > Right_Margin do
  4025.           begin
  4026.             if not Do_Word_Wrap (Select_Mode, Center_Cursor) then
  4027.               Exit;
  4028.           end;
  4029.  
  4030.  
  4031.  
  4032.         { -------------------------------------------------------- }
  4033.         {                                                          }
  4034.         { If LineEnd - LineStart > Right_Margin then set CurPtr    }
  4035.         { to Right_Margin on current line.  Otherwise we set the   }
  4036.         { CurPtr to LineEnd.  This gyration sets up the conditions }
  4037.         { to test for time of loop exit.                           }
  4038.         {                                                          }
  4039.         { -------------------------------------------------------- }
  4040.  
  4041.  
  4042.         if LineEnd (CurPtr) - LineStart (CurPtr) > Right_Margin then
  4043.           SetCurPtr (LineStart (CurPtr) + Right_Margin, Select_Mode)
  4044.         else
  4045.           SetCurPtr (LineEnd (CurPtr), Select_Mode);
  4046.  
  4047.       until ((CurPtr >= BufLen) or (CurPtr >= BlankLine - 2));
  4048.  
  4049.     end;
  4050.  
  4051.  
  4052.  
  4053.   { --------------------------------------------------------------------- }
  4054.   {                                                                       }
  4055.   { If not at the end of the document reset CurPtr to start of next line. }
  4056.   { This should be a blank line between paragraphs.                       }
  4057.   {                                                                       }
  4058.   { --------------------------------------------------------------------- }
  4059.  
  4060.  
  4061.   if CurPtr < BufLen then
  4062.     SetCurPtr (LineMove (CurPtr, 1), Select_Mode);
  4063.  
  4064.  
  4065.   Reformat_Paragraph := True;
  4066.  
  4067.  
  4068. end; { TEditor.Reformat_Paragraph }
  4069.  
  4070. { REFORM - Stop. }
  4071.  
  4072.  
  4073.  
  4074. { -------------------------------------------------------------------------- }
  4075.  
  4076.  
  4077.  
  4078. { WRAP - Start. }
  4079.  
  4080. procedure TEditor.Remove_EOL_Spaces (Select_Mode : Byte);
  4081.  
  4082.  
  4083.   { ----------------------------------------------------------- }
  4084.   {                                                             }
  4085.   { This procedure tests to see if there are consecutive spaces }
  4086.   { at the end of a line (EOL).  If so, we delete all spaces    }
  4087.   { after the last non-space character to the end of line.      }
  4088.   { We then reset the CurPtr to where we ended up at.           }
  4089.   {                                                             }
  4090.   { ----------------------------------------------------------- }
  4091.  
  4092.  
  4093. VAR
  4094.  
  4095.   C : Word;           { Current pointer when we come into procedure. }
  4096.   E : Word;           { End of line.                                 }
  4097.   P : Word;           { Position of pointer at any given moment.     }
  4098.   S : Word;           { Start of a line.                             }
  4099.  
  4100. begin
  4101.  
  4102.   C := CurPtr;
  4103.   E := LineEnd (CurPtr);
  4104.   P := E;
  4105.   S := LineStart (CurPtr);
  4106.  
  4107.  
  4108.  
  4109.   { ------------------------------------------------------ }
  4110.   {                                                        }
  4111.   { Start at the end of a line and move towards the start. }
  4112.   { Find first non-space character in that direction.      }
  4113.   {                                                        }
  4114.   { ------------------------------------------------------ }
  4115.  
  4116.  
  4117.   while (P > S) and (BufChar (PrevChar (P)) = #32) do
  4118.     P := PrevChar (P);
  4119.  
  4120.  
  4121.  
  4122.   { ---------------------------------------- }
  4123.   {                                          }
  4124.   { If we found any spaces then delete them. }
  4125.   {                                          }
  4126.   { ---------------------------------------- }
  4127.  
  4128.  
  4129.   if P < E then
  4130.     begin
  4131.  
  4132.       SetSelect (P, E, True);
  4133.       DeleteSelect;
  4134.  
  4135.       { MARK - Start. }
  4136.  
  4137.       Update_Place_Markers (0, E - P, P, E);
  4138.  
  4139.       { MARK - Stop. } { This will update Place_Marker for EOL deletions. }
  4140.                        { All other deletions are handled by DeleteRange.  }
  4141.  
  4142.     end;
  4143.  
  4144.  
  4145.  
  4146.   { --------------------------------------------------- }
  4147.   {                                                     }
  4148.   { If C, our pointer when we came into this procedure, }
  4149.   { is less than the CurPtr then reset CurPtr to C so   }
  4150.   { cursor is where we started.  Otherwise, set it to   }
  4151.   { the new CurPtr, for we have deleted characters.     }
  4152.   {                                                     }
  4153.   { --------------------------------------------------- }
  4154.  
  4155.  
  4156.   if C < CurPtr then
  4157.     SetCurPtr (C, Select_Mode)
  4158.   else
  4159.     SetCurPtr (CurPtr, Select_Mode);
  4160.  
  4161.  
  4162. end; { TEditor.Remove_EOL_Spaces }
  4163.  
  4164. { WRAP - Stop. }
  4165.  
  4166.  
  4167.  
  4168. { -------------------------------------------------------------------------- }
  4169.  
  4170.  
  4171.  
  4172. procedure TEditor.Replace;
  4173.  
  4174. VAR
  4175.  
  4176.   ReplaceRec : TReplaceDialogRec;
  4177.  
  4178. begin
  4179.  
  4180.   with ReplaceRec do
  4181.   begin
  4182.  
  4183.     Find := FindStr;
  4184.     Replace := ReplaceStr;
  4185.     Options := EditorFlags;
  4186.  
  4187.     if EditorDialog (edReplace, @ReplaceRec) <> Views.cmCancel then
  4188.     begin
  4189.       FindStr := Find;
  4190.       ReplaceStr := Replace;
  4191.       EditorFlags := Options or efDoReplace;
  4192.       DoSearchReplace;
  4193.     end;
  4194.   end;
  4195.  
  4196.  
  4197. end; { TEditor.Replace }
  4198.  
  4199.  
  4200.  
  4201. { -------------------------------------------------------------------------- }
  4202.  
  4203.  
  4204.  
  4205. { SCRLDN - Start. }
  4206.  
  4207. procedure TEditor.Scroll_Down;
  4208.  
  4209.  
  4210.   { -------------------------------------------------------------- }
  4211.   {                                                                }
  4212.   { This procedure will scroll the screen up, and always keep      }
  4213.   { the cursor on the CurPos.Y position, but not necessarily on    }
  4214.   { the CurPos.X.  If CurPos.Y scrolls off the screen, the cursor  }
  4215.   { will stay in the upper left corner of the screen.  This will   }
  4216.   { simulate the same process in the IDE.  The CurPos.X coordinate }
  4217.   { only messes up if we are on long lines and we then encounter   }
  4218.   { a shorter or blank line beneath the current one as we scroll.  }
  4219.   { In that case, it goes to the end of the new line.              }
  4220.   {                                                                }
  4221.   { -------------------------------------------------------------- }
  4222.  
  4223.  
  4224. VAR
  4225.  
  4226.   C : Word;           { Position of CurPtr when we enter procedure. }
  4227.   P : Word;           { Position of CurPtr at any given time.       }
  4228.   W : Objects.TPoint; { CurPos.Y of CurPtr and P ('.X and '.Y).     }
  4229.  
  4230. begin
  4231.  
  4232.  
  4233.  
  4234.   { ---------------------------------------------------------------------- }
  4235.   {                                                                        }
  4236.   { Remember current cursor position.  Remember current CurPos.Y position. }
  4237.   { Now issue the equivalent of a [Ctrl]-[End] command so the cursor will  }
  4238.   { go to the bottom of the current screen.  Reset the cursor to this new  }
  4239.   { position and then send FALSE to TrackCursor so we fool it into         }
  4240.   { incrementing Delta.Y by only +1.  If we didn't do this it would try    }
  4241.   { to center the cursor on the screen by fiddling with Delta.Y.           }
  4242.   {                                                                        }
  4243.   { ---------------------------------------------------------------------- }
  4244.  
  4245.  
  4246.   C := CurPtr;
  4247.   W.X := CurPos.Y;
  4248.  
  4249.   P := LineMove (CurPtr, Delta.Y - CurPos.Y + Size.Y);
  4250.  
  4251.   SetCurPtr (P, 0);
  4252.  
  4253.   TrackCursor (False);
  4254.  
  4255.  
  4256.  
  4257.   { -------------------------------------------------------------------- }
  4258.   {                                                                      }
  4259.   { Now remember where the new CurPos.Y is.  See if distance between new }
  4260.   { CurPos.Y and old CurPos.Y are greater than the current screen size.  }
  4261.   { If they are, we need to move cursor position itself down by one.     }
  4262.   { Otherwise, send the cursor back to our original CurPtr.              }
  4263.   {                                                                      }
  4264.   { -------------------------------------------------------------------- }
  4265.  
  4266.  
  4267.   W.Y := CurPos.Y;
  4268.  
  4269.   if W.Y - W.X > Size.Y - 1 then
  4270.     SetCurPtr (LineMove (C, 1), 0)
  4271.   else
  4272.     SetCurPtr (C, 0);
  4273.  
  4274.  
  4275. end; { TEditor.Scroll_Down }
  4276.  
  4277. { SCRLDN - Stop. } { Added this complete procedure to simulate IDE function. }
  4278.  
  4279.  
  4280.  
  4281. { -------------------------------------------------------------------------- }
  4282.  
  4283.  
  4284.  
  4285. { SCRLUP - Start. }
  4286.  
  4287. procedure TEditor.Scroll_Up;
  4288.  
  4289.  
  4290.   { -------------------------------------------------------------- }
  4291.   {                                                                }
  4292.   { This procedure will scroll the screen down, and always keep    }
  4293.   { the cursor on the CurPos.Y position, but not necessarily on    }
  4294.   { the CurPos.X.  If CurPos.Y scrolls off the screen, the cursor  }
  4295.   { will stay in the bottom left corner of the screen.  This will  }
  4296.   { simulate the same process in the IDE.  The CurPos.X coordinate }
  4297.   { only messes up if we are on long lines and we then encounter   }
  4298.   { a shorter or blank line beneath the current one as we scroll.  }
  4299.   { In that case, it goes to the end of the new line.              }
  4300.   {                                                                }
  4301.   { -------------------------------------------------------------- }
  4302.  
  4303.  
  4304. VAR
  4305.  
  4306.   C : Word;           { Position of CurPtr when we enter procedure. }
  4307.   P : Word;           { Position of CurPtr at any given time.       }
  4308.   W : Objects.TPoint; { CurPos.Y of CurPtr and P ('.X and '.Y).     }
  4309.  
  4310. begin
  4311.  
  4312.  
  4313.  
  4314.   { ---------------------------------------------------------------------- }
  4315.   {                                                                        }
  4316.   { Remember current cursor position.  Remember current CurPos.Y position. }
  4317.   { Now issue the equivalent of a [Ctrl]-[Home] command so the cursor will }
  4318.   { go to the top of the current screen.  Reset the cursor to this new     }
  4319.   { position and then send FALSE to TrackCursor so we fool it into         }
  4320.   { decrementing Delta.Y by only -1.  If we didn't do this it would try    }
  4321.   { to center the cursor on the screen by fiddling with Delta.Y.           }
  4322.   {                                                                        }
  4323.   { ---------------------------------------------------------------------- }
  4324.  
  4325.  
  4326.   C := CurPtr;
  4327.   W.Y := CurPos.Y;
  4328.  
  4329.   P := LineMove (CurPtr, -(CurPos.Y - Delta.Y + 1));
  4330.  
  4331.   SetCurPtr (P, 0);
  4332.  
  4333.   TrackCursor (False);
  4334.  
  4335.  
  4336.  
  4337.   { -------------------------------------------------------------------- }
  4338.   {                                                                      }
  4339.   { Now remember where the new CurPos.Y is.  See if distance between new }
  4340.   { CurPos.Y and old CurPos.Y are greater than the current screen size.  }
  4341.   { If they are, we need to move the cursor position itself up by one.   }
  4342.   { Otherwise, send the cursor back to our original CurPtr.              }
  4343.   {                                                                      }
  4344.   { -------------------------------------------------------------------- }
  4345.  
  4346.  
  4347.   W.X := CurPos.Y;
  4348.  
  4349.   if W.Y - W.X > Size.Y - 1 then
  4350.     SetCurPtr (LineMove (C, -1), 0)
  4351.   else
  4352.     SetCurPtr (C, 0);
  4353.  
  4354.  
  4355. end; { TEditor.Scroll_Up }
  4356.  
  4357. { SCRLDN - Stop. } { Added this complete procedure to simulate IDE function. }
  4358.  
  4359.  
  4360.  
  4361. { -------------------------------------------------------------------------- }
  4362.  
  4363.  
  4364.  
  4365. procedure TEditor.ScrollTo (X, Y : Integer);
  4366.  
  4367. begin
  4368.  
  4369.   X := Max (0, Min (X, Limit.X - Size.X));
  4370.   Y := Max (0, Min (Y, Limit.Y - Size.Y));
  4371.  
  4372.   if (X <> Delta.X) or (Y <> Delta.Y) then
  4373.   begin
  4374.     Delta.X := X;
  4375.     Delta.Y := Y;
  4376.     Update (ufView);
  4377.   end;
  4378.  
  4379.  
  4380. end; { TEditor.ScrollTo }
  4381.  
  4382.  
  4383.  
  4384. { -------------------------------------------------------------------------- }
  4385.  
  4386.  
  4387.  
  4388. function TEditor.Search (FindStr : String; Opts : Word) : Boolean;
  4389.  
  4390. VAR
  4391.  
  4392.   I   : Word;
  4393.   Pos : Word;
  4394.  
  4395. begin
  4396.  
  4397.   Search := False;
  4398.   Pos := CurPtr;
  4399.  
  4400.   repeat
  4401.  
  4402.     if Opts and efCaseSensitive <> 0 then
  4403.       I := Scan (Buffer^[BufPtr (Pos)], BufLen - Pos, FindStr)
  4404.     else
  4405.       I := IScan (Buffer^[BufPtr (Pos)], BufLen - Pos, FindStr);
  4406.  
  4407.     if (I <> sfSearchFailed) then
  4408.     begin
  4409.  
  4410.       Inc (I, Pos);
  4411.  
  4412.       if (Opts and efWholeWordsOnly = 0) or
  4413.          not (((I <> 0) and (BufChar (I - 1) in WordChars)) or
  4414.               ((I + Length (FindStr) <> BufLen) and
  4415.                (BufChar (I + Length (FindStr)) in WordChars))) then
  4416.         begin
  4417.           Lock;
  4418.           SetSelect (I, I + Length (FindStr), False);
  4419.           TrackCursor (not CursorVisible);
  4420.           Unlock;
  4421.           Search := True;
  4422.           Exit;
  4423.         end
  4424.       else
  4425.         Pos := I + 1;
  4426.  
  4427.     end;
  4428.  
  4429.   until I = sfSearchFailed;
  4430.  
  4431.  
  4432. end; { TEditor.Search }
  4433.  
  4434.  
  4435.  
  4436. { -------------------------------------------------------------------------- }
  4437.  
  4438.  
  4439.  
  4440. { SELWRD - Start. }
  4441.  
  4442. procedure TEditor.Select_Word;
  4443.  
  4444.  
  4445.   { ------------------------------------------------------------------ }
  4446.   {                                                                    }
  4447.   { This procedure will select the a word to put into the clipboard.   }
  4448.   { I've added it just to maintain compatibility with the IDE editor.  }
  4449.   { Note that selection starts at the current cursor position and ends }
  4450.   { when a space or the end of line is encountered.                    }
  4451.   {                                                                    }
  4452.   { ------------------------------------------------------------------ }
  4453.  
  4454.  
  4455. VAR
  4456.  
  4457.   E : Word;           { End of the current line.                           }
  4458.   Select_Mode : Byte; { Allows us to turn select mode on inside procedure. }
  4459.  
  4460. begin
  4461.  
  4462.   E := LineEnd (CurPtr);
  4463.  
  4464.  
  4465.  
  4466.   { ----------------------------------------------------------- }
  4467.   {                                                             }
  4468.   { If the cursor is on a space or at the end of a line, abort. }
  4469.   { Stupid action on users part for you can't select blanks!    }
  4470.   {                                                             }
  4471.   { ----------------------------------------------------------- }
  4472.  
  4473.  
  4474.   if (BufChar (CurPtr) = #32) or (CurPtr = E) then
  4475.     Exit;
  4476.  
  4477.  
  4478.  
  4479.   { ------------------------------------------------------------ }
  4480.   {                                                              }
  4481.   { Turn on select mode and tell editor to start selecting text. }
  4482.   { As long as we have a character > a space (this is done to    }
  4483.   { exclude CR/LF pairs at end of a line) and we are NOT at the  }
  4484.   { end of a line, set the CurPtr to the next character.         }
  4485.   { Once we find a space or CR/LF, selection is done and we      }
  4486.   { automatically put the selected word into the Clipboard.      }
  4487.   {                                                              }
  4488.   { ------------------------------------------------------------ }
  4489.  
  4490.  
  4491.   Select_Mode := smExtend;
  4492.   StartSelect;
  4493.  
  4494.   while (BufChar (NextChar (CurPtr)) > #32) and (CurPtr < E) do
  4495.     SetCurPtr (NextChar (CurPtr), Select_Mode);
  4496.  
  4497.   SetCurPtr (NextChar (CurPtr), Select_Mode);
  4498.   ClipCopy;
  4499.  
  4500.  
  4501. end; {TEditor.Select_Word }
  4502.  
  4503. {SELWRD - Stop. }
  4504.  
  4505.  
  4506.  
  4507. { -------------------------------------------------------------------------- }
  4508.  
  4509.  
  4510.  
  4511. procedure TEditor.SetBufLen (Length : Word);
  4512.  
  4513.  
  4514. begin
  4515.  
  4516.   BufLen := Length;
  4517.   GapLen := BufSize - Length;
  4518.  
  4519.   SelStart := 0;
  4520.   SelEnd := 0;
  4521.  
  4522.   CurPtr := 0;
  4523.  
  4524.   Longint (CurPos) := 0;
  4525.   Longint (Delta) := 0;
  4526.  
  4527.   Limit.X := MaxLineLength;
  4528.   Limit.Y := CountLines (Buffer^[GapLen], BufLen) + 1;
  4529.  
  4530.   DrawLine := 0;
  4531.   DrawPtr := 0;
  4532.  
  4533.   DelCount := 0;
  4534.   InsCount := 0;
  4535.  
  4536.   Modified := False;
  4537.   Update (ufView);
  4538.  
  4539.  
  4540. end; { TEditor.SetBufLen }
  4541.  
  4542.  
  4543.  
  4544. { -------------------------------------------------------------------------- }
  4545.  
  4546.  
  4547.  
  4548. function TEditor.SetBufSize (NewSize : Word) : Boolean;
  4549.  
  4550. begin
  4551.  
  4552.   SetBufSize := NewSize <= BufSize;
  4553.  
  4554.  
  4555. end; { TEditor.SetBufSize }
  4556.  
  4557.  
  4558.  
  4559. { -------------------------------------------------------------------------- }
  4560.  
  4561.  
  4562.  
  4563. procedure TEditor.SetCmdState (Command : Word; Enable : Boolean);
  4564.  
  4565. VAR
  4566.  
  4567.   S : Views.TCommandSet;
  4568.  
  4569. begin
  4570.  
  4571.   S := [Command];
  4572.  
  4573.   if Enable and (State and sfActive <> 0) then
  4574.     EnableCommands (S)
  4575.   else
  4576.     DisableCommands (S);
  4577.  
  4578.  
  4579. end; { TEditor.SetCmdState }
  4580.  
  4581.  
  4582.  
  4583. { -------------------------------------------------------------------------- }
  4584.  
  4585.  
  4586.  
  4587. procedure TEditor.SetCurPtr (P : Word; SelectMode : Byte);
  4588.  
  4589. VAR
  4590.  
  4591.   Anchor : Word;
  4592.  
  4593. begin
  4594.  
  4595.   if SelectMode and smExtend = 0 then
  4596.     Anchor := P
  4597.   else
  4598.     if CurPtr = SelStart then
  4599.       Anchor := SelEnd
  4600.     else
  4601.       Anchor := SelStart;
  4602.  
  4603.   if P < Anchor then
  4604.     begin
  4605.  
  4606.       if SelectMode and smDouble <> 0 then
  4607.       begin
  4608.         P := PrevLine (NextLine (P));
  4609.         Anchor := NextLine (PrevLine (Anchor));
  4610.       end;
  4611.  
  4612.       SetSelect (P, Anchor, True);
  4613.  
  4614.     end
  4615.   else
  4616.     begin
  4617.  
  4618.       if SelectMode and smDouble <> 0 then
  4619.       begin
  4620.         P := NextLine (P);
  4621.         Anchor := PrevLine (NextLine (Anchor));
  4622.       end;
  4623.  
  4624.       SetSelect (Anchor, P, False);
  4625.  
  4626.     end;
  4627.  
  4628.  
  4629. end; { TEditor.SetCurPtr }
  4630.  
  4631.  
  4632.  
  4633. { -------------------------------------------------------------------------- }
  4634.  
  4635.  
  4636.  
  4637. { MARK - Start. }
  4638.  
  4639. procedure TEditor.Set_Place_Marker (Element : Byte);
  4640.  
  4641.  
  4642.   { -------------------------------------------------------------------- }
  4643.   {                                                                      }
  4644.   { This procedure sets a place marker for the CurPtr if ^K# is pressed. }
  4645.   {                                                                      }
  4646.   { -------------------------------------------------------------------- }
  4647.  
  4648.  
  4649. begin
  4650.  
  4651.   if not IsClipboard then
  4652.     Place_Marker[Element] := CurPtr;
  4653.  
  4654.  
  4655. end; { TEditor.Set_Place_Marker }
  4656.  
  4657. { MARK - Stop. }
  4658.  
  4659.  
  4660.  
  4661. { -------------------------------------------------------------------------- }
  4662.  
  4663.  
  4664.  
  4665. { RMSET - Start. }
  4666.  
  4667. procedure TEditor.Set_Right_Margin;
  4668.  
  4669.  
  4670.   { ----------------------------------------- }
  4671.   {                                           }
  4672.   { This procedure will bring up a dialog box }
  4673.   { that allows the user to set Right_Margin. }
  4674.   { Values must be < MaxLineLength and > 9.   }
  4675.   {                                           }
  4676.   { ----------------------------------------- }
  4677.  
  4678.  
  4679. VAR
  4680.  
  4681.   Code        : Integer;          { Used for Val conversion.      }
  4682.   Margin_Data : TRightMarginRec;  { Holds dialog results.         }
  4683.   Temp_Value  : Integer;          { Holds converted dialog value. }
  4684.  
  4685. begin
  4686.  
  4687.   with Margin_Data do
  4688.     begin
  4689.  
  4690.       Str (Right_Margin, Margin_Position);
  4691.  
  4692.       if EditorDialog (edRightMargin, @Margin_Position) <> Views.cmCancel then
  4693.         begin
  4694.           val (Margin_Position, Temp_Value, Code);
  4695.           if (Temp_Value <= MaxLineLength) and (Temp_Value > 9) then
  4696.             Right_Margin := Temp_Value;
  4697.         end;
  4698.  
  4699.     end;
  4700.  
  4701.  
  4702. end; { TEditor.Set_Right_Margin }
  4703.  
  4704.  
  4705. { RMSET - Stop. }
  4706.  
  4707.  
  4708.  
  4709. { -------------------------------------------------------------------------- }
  4710.  
  4711.  
  4712.  
  4713. procedure TEditor.SetSelect (NewStart, NewEnd : Word; CurStart : Boolean);
  4714.  
  4715. VAR
  4716.  
  4717.   Flags : Byte;
  4718.   P     : Word;
  4719.   L     : Word;
  4720.  
  4721. begin
  4722.  
  4723.   if CurStart then
  4724.     P := NewStart
  4725.   else
  4726.     P := NewEnd;
  4727.  
  4728.   Flags := ufUpdate;
  4729.  
  4730.   if (NewStart <> SelStart) or (NewEnd <> SelEnd) then
  4731.     if (NewStart <> NewEnd) or (SelStart <> SelEnd) then
  4732.       Flags := ufView;
  4733.  
  4734.   if P <> CurPtr then
  4735.   begin
  4736.  
  4737.     if P > CurPtr then
  4738.       begin
  4739.         L := P - CurPtr;
  4740.         Move (Buffer^[CurPtr + GapLen], Buffer^[CurPtr], L);
  4741.         Inc (CurPos.Y, CountLines (Buffer^[CurPtr], L));
  4742.         CurPtr := P;
  4743.       end
  4744.     else
  4745.       begin
  4746.         L := CurPtr - P;
  4747.         CurPtr := P;
  4748.         Dec (CurPos.Y, CountLines (Buffer^[CurPtr], L));
  4749.         Move (Buffer^[CurPtr], Buffer^[CurPtr + GapLen], L);
  4750.       end;
  4751.  
  4752.     DrawLine := CurPos.Y;
  4753.     DrawPtr := LineStart (P);
  4754.  
  4755.     CurPos.X := CharPos (DrawPtr, P);
  4756.  
  4757.     DelCount := 0;
  4758.     InsCount := 0;
  4759.  
  4760.     SetBufSize (BufLen);
  4761.  
  4762.   end;
  4763.  
  4764.   SelStart := NewStart;
  4765.   SelEnd := NewEnd;
  4766.  
  4767.   Update (Flags);
  4768.  
  4769.  
  4770. end; { TEditor.Select }
  4771.  
  4772.  
  4773.  
  4774. { -------------------------------------------------------------------------- }
  4775.  
  4776.  
  4777.  
  4778. procedure TEditor.SetState (AState : Word; Enable : Boolean);
  4779.  
  4780. begin
  4781.  
  4782.   TView.SetState (AState, Enable);
  4783.  
  4784.   case AState of
  4785.  
  4786.     Views.sfActive: begin
  4787.                       if HScrollBar <> nil then
  4788.                         HScrollBar^.SetState (Views.sfVisible, Enable);
  4789.                       if VScrollBar <> nil then
  4790.                         VScrollBar^.SetState (Views.sfVisible, Enable);
  4791.                       if Indicator <> nil then
  4792.                         Indicator^.SetState (Views.sfVisible, Enable);
  4793.                       UpdateCommands;
  4794.                     end;
  4795.  
  4796.     Views.sfExposed: if Enable then Unlock;
  4797.  
  4798.   end;
  4799.  
  4800.  
  4801. end; { TEditor.SetState }
  4802.  
  4803.  
  4804.  
  4805. { -------------------------------------------------------------------------- }
  4806.  
  4807.  
  4808.  
  4809. { PRETAB - Start. }
  4810.  
  4811. procedure TEditor.Set_Tabs;
  4812.  
  4813.  
  4814.  
  4815.   { ----------------------------------------- }
  4816.   {                                           }
  4817.   { This procedure will bring up a dialog box }
  4818.   { that allows the user to set tab stops.    }
  4819.   {                                           }
  4820.   { ----------------------------------------- }
  4821.  
  4822.  
  4823. VAR
  4824.  
  4825.   Index    : Integer;      { Index into string array. }
  4826.   Tab_Data : TTabStopRec;  { Holds dialog results.    }
  4827.  
  4828. begin
  4829.  
  4830.   with Tab_Data do
  4831.     begin
  4832.  
  4833.  
  4834.  
  4835.       { --------------------------------------------- }
  4836.       {                                               }
  4837.       { Assign current Tab_Settings to Tab_String.    }
  4838.       { Bring up the tab dialog so user can set tabs. }
  4839.       {                                               }
  4840.       { --------------------------------------------- }
  4841.  
  4842.  
  4843.       Tab_String := Copy (Tab_Settings, 1, Tab_Stop_Length);
  4844.  
  4845.       if EditorDialog (edSetTabStops, @Tab_String) <> Views.cmCancel then
  4846.         begin
  4847.  
  4848.  
  4849.  
  4850.           { --------------------------------------------------------------- }
  4851.           {                                                                 }
  4852.           { If Tab_String comes back as empty then set Tab_Settings to nil. }
  4853.           { Otherwise, find the last character in Tab_String that is not    }
  4854.           { a space and copy Tab_String into Tab_Settings up to that spot.  }
  4855.           {                                                                 }
  4856.           { --------------------------------------------------------------- }
  4857.  
  4858.  
  4859.           if Length (Tab_String) = 0 then
  4860.             begin
  4861.               FillChar (Tab_Settings, SizeOf (Tab_Settings), #0);
  4862.               Tab_Settings[0] := #0;
  4863.               Exit;
  4864.             end
  4865.           else
  4866.             begin
  4867.               Index := Length (Tab_String);
  4868.               while Tab_String[Index] <= #32 do
  4869.                 Dec (Index);
  4870.               Tab_Settings := Copy (Tab_String, 1, Index);
  4871.             end;
  4872.  
  4873.         end;
  4874.  
  4875.   end;
  4876.  
  4877.  
  4878. end; { TEditor.Set_Tabs }
  4879.  
  4880. { PRETAB - Stop. }
  4881.  
  4882.  
  4883.  
  4884. { -------------------------------------------------------------------------- }
  4885.  
  4886.  
  4887.  
  4888. procedure TEditor.StartSelect;
  4889.  
  4890. begin
  4891.  
  4892.   HideSelect;
  4893.   Selecting := True;
  4894.  
  4895.  
  4896. end; { TEditor.StartSelect }
  4897.  
  4898.  
  4899.  
  4900. { -------------------------------------------------------------------------- }
  4901.  
  4902.  
  4903.  
  4904. procedure TEditor.Store (var S : Objects.TStream);
  4905.  
  4906. begin
  4907.  
  4908.   TView.Store (S);
  4909.  
  4910.   PutPeerViewPtr (S, HScrollBar);
  4911.   PutPeerViewPtr (S, VScrollBar);
  4912.   PutPeerViewPtr (S, Indicator);
  4913.   S.Write (BufSize, SizeOf (Word));
  4914.  
  4915.  
  4916.   { STORE - Start. }
  4917.  
  4918.   { S.Write (Canundo, SizeOf (Boolean)); }
  4919.  
  4920.   { STORE - Stop. } {This item caused load/store bug. }
  4921.  
  4922.  
  4923.   { STATS  - Start. }
  4924.   { JLINE  - Start. }
  4925.   { MARK   - Start. }
  4926.   { RMSET  - Start. }
  4927.   { PRETAB - Start. }
  4928.   { WRAP   - Start. }
  4929.  
  4930.   S.Write (AutoIndent,   SizeOf (AutoIndent));
  4931.   S.Write (Line_Number,  SizeOf (Line_Number));
  4932.   S.Write (Place_Marker, SizeOf (Place_Marker));
  4933.   S.Write (Right_Margin, SizeOf (Right_Margin));
  4934.   S.Write (Tab_Settings, SizeOf (Tab_Settings));
  4935.   S.Write (Word_Wrap,    SizeOf (Word_Wrap));
  4936.  
  4937.   { WRAP   - Stop. }
  4938.   { PRETAB - Stop. }
  4939.   { RMSET  - Stop. }
  4940.   { MARK   - Stop. }
  4941.   { JLINE  - Stop. }
  4942.   { STATS  - Stop. } { Added these to allow load/store operations. }
  4943.  
  4944.  
  4945. end; { Editor.Store }
  4946.  
  4947.  
  4948.  
  4949. { -------------------------------------------------------------------------- }
  4950.  
  4951.  
  4952.  
  4953. { PRETAB - Start. }
  4954.  
  4955.  
  4956. procedure TEditor.Tab_Key (Select_Mode : Byte);
  4957.  
  4958.  
  4959.   { ------------------------------------------------------------------ }
  4960.   {                                                                    }
  4961.   { This function determines if we are in overstrike or insert mode,   }
  4962.   { and then moves the cursor if overstrike, or adds spaces if insert. }
  4963.   {                                                                    }
  4964.   { ------------------------------------------------------------------ }
  4965.  
  4966.  
  4967. VAR
  4968.  
  4969.   E        : Word;                   { End of current line.                }
  4970.   Index    : Integer;                { Loop counter.                       }
  4971.   Position : Integer;                { CurPos.X position.                  }
  4972.   S        : Word;                   { Start of current line.              }
  4973.   Spaces   : array [1..80] of Char;  { Array to hold spaces for insertion. }
  4974.  
  4975.  
  4976. begin
  4977.  
  4978.   E := LineEnd (CurPtr);
  4979.   S := LineStart (CurPtr);
  4980.  
  4981.  
  4982.  
  4983.   { -------------------------------------------- }
  4984.   {                                              }
  4985.   { Find the current horizontal cursor position. }
  4986.   { Now loop through the Tab_Settings string and }
  4987.   { find the next available tab stop.            }
  4988.   {                                              }
  4989.   { -------------------------------------------- }
  4990.  
  4991.  
  4992.   Position := CurPos.X + 1;
  4993.  
  4994.   repeat
  4995.     Inc (Position);
  4996.   until (Tab_Settings[Position] <> #32) or (Position >= Ord (Tab_Settings[0]));
  4997.  
  4998.   E := CurPos.X;
  4999.   Index := 1;
  5000.  
  5001.  
  5002.  
  5003.   { ---------------------------------------------------- }
  5004.   {                                                      }
  5005.   { Now we enter a loop to go to the next tab position.  }
  5006.   { If we are in overwrite mode, we just move the cursor }
  5007.   { through the text to the next tab stop.  If we are in }
  5008.   { insert mode, we add spaces to the Spaces array for   }
  5009.   { the number of times we loop.                         }
  5010.   {                                                      }
  5011.   { ---------------------------------------------------- }
  5012.  
  5013.  
  5014.   while Index < Position - E do
  5015.     begin
  5016.  
  5017.       if Overwrite then
  5018.         begin
  5019.           if (Position > LineEnd (CurPtr) - LineStart (CurPtr))
  5020.               or (Position > Ord (Tab_Settings[0])) then
  5021.             begin
  5022.               SetCurPtr (LineStart (LineMove (CurPtr, 1)), Select_Mode);
  5023.               Exit;
  5024.             end
  5025.           else
  5026.             if CurPtr < BufLen then
  5027.               SetCurPtr (NextChar (CurPtr), Select_Mode);
  5028.         end
  5029.       else
  5030.         begin
  5031.           if (Position > Right_Margin) or (Position > Ord (Tab_Settings[0])) then
  5032.             begin
  5033.               SetCurPtr (LineStart (LineMove (CurPtr, 1)), Select_Mode);
  5034.               Exit;
  5035.             end
  5036.           else
  5037.             Spaces[Index] := #32;
  5038.         end;
  5039.  
  5040.       Inc (Index);
  5041.  
  5042.   end;
  5043.  
  5044.  
  5045.  
  5046.   { -------------------------------------------------------------------- }
  5047.   {                                                                      }
  5048.   { If we are insert mode, we insert spaces to the next tab stop.        }
  5049.   { When we're all done, the cursor will be sitting on the new tab stop. }
  5050.   {                                                                      }
  5051.   { -------------------------------------------------------------------- }
  5052.  
  5053.  
  5054.   if not OverWrite then
  5055.     InsertText (@Spaces, Index - 1, False);
  5056.  
  5057.  
  5058. end; { TEditor.Tab_Key }
  5059.  
  5060. { PRETAB - Stop. }
  5061.  
  5062.  
  5063.  
  5064. { -------------------------------------------------------------------------- }
  5065.  
  5066.  
  5067.  
  5068. procedure TEditor.ToggleInsMode;
  5069.  
  5070. begin
  5071.  
  5072.   Overwrite := not Overwrite;
  5073.   SetState (sfCursorIns, not GetState (sfCursorIns));
  5074.  
  5075.  
  5076. end; { TEditor.ToggleInsMode }
  5077.  
  5078.  
  5079.  
  5080. { -------------------------------------------------------------------------- }
  5081.  
  5082.  
  5083.  
  5084. procedure TEditor.TrackCursor (Center : Boolean);
  5085.  
  5086. begin
  5087.  
  5088.   if Center then
  5089.     ScrollTo (CurPos.X - Size.X + 1, CurPos.Y - Size.Y div 2)
  5090.   else
  5091.     ScrollTo (Max (CurPos.X - Size.X + 1, Min (Delta.X, CurPos.X)),
  5092.               Max (CurPos.Y - Size.Y + 1, Min (Delta.Y, CurPos.Y)));
  5093.  
  5094.  
  5095. end; { TEditor.TrackCursor }
  5096.  
  5097.  
  5098.  
  5099. { -------------------------------------------------------------------------- }
  5100.  
  5101.  
  5102.  
  5103. procedure TEditor.Undo;
  5104.  
  5105. VAR
  5106.  
  5107.   Length : Word;
  5108.  
  5109. begin
  5110.  
  5111.   if (DelCount <> 0) or (InsCount <> 0) then
  5112.   begin
  5113.  
  5114.     { MARK - Start. }
  5115.  
  5116.     Update_Place_Markers (DelCount, 0, CurPtr, CurPtr + DelCount);
  5117.  
  5118.     { MARK - Stop. } { Update Place_Marker array if we undelete text. }
  5119.  
  5120.     SelStart := CurPtr - InsCount;
  5121.     SelEnd := CurPtr;
  5122.     Length := DelCount;
  5123.     DelCount := 0;
  5124.     InsCount := 0;
  5125.     InsertBuffer (Buffer, CurPtr + GapLen - Length, Length, False, True);
  5126.  
  5127.   end;
  5128.  
  5129.  
  5130. end; { TEditor.Undo }
  5131.  
  5132.  
  5133.  
  5134. { -------------------------------------------------------------------------- }
  5135.  
  5136.  
  5137.  
  5138. procedure TEditor.Unlock;
  5139.  
  5140. begin
  5141.  
  5142.   if LockCount > 0 then
  5143.   begin
  5144.     Dec (LockCount);
  5145.     if LockCount = 0 then
  5146.       DoUpdate;
  5147.   end;
  5148.  
  5149.  
  5150. end; { TEditor.Unlock }
  5151.  
  5152.  
  5153.  
  5154. { -------------------------------------------------------------------------- }
  5155.  
  5156.  
  5157.  
  5158. procedure TEditor.Update (AFlags : Byte);
  5159.  
  5160. begin
  5161.  
  5162.   UpdateFlags := UpdateFlags or AFlags;
  5163.  
  5164.   if LockCount = 0 then
  5165.     DoUpdate;
  5166.  
  5167.  
  5168. end; { TEditor.Update }
  5169.  
  5170.  
  5171.  
  5172. { -------------------------------------------------------------------------- }
  5173.  
  5174.  
  5175.  
  5176. procedure TEditor.UpdateCommands;
  5177.  
  5178. begin
  5179.  
  5180.   SetCmdState (cmUndo, (DelCount <> 0) or (InsCount <> 0));
  5181.  
  5182.   if not IsClipboard then
  5183.     begin
  5184.       SetCmdState (cmCut, HasSelection);
  5185.       SetCmdState (cmCopy, HasSelection);
  5186.       SetCmdState (cmPaste, (Clipboard <> nil) and (Clipboard^.HasSelection));
  5187.     end;
  5188.  
  5189.   SetCmdState (cmClear, HasSelection);
  5190.   SetCmdState (cmFind, True);
  5191.   SetCmdState (cmReplace, True);
  5192.   SetCmdState (cmSearchAgain, True);
  5193.  
  5194.  
  5195. end; { TEditor.UpdateCommands }
  5196.  
  5197.  
  5198.  
  5199. { -------------------------------------------------------------------------- }
  5200.  
  5201.  
  5202.  
  5203. { MARK - Start. }
  5204.  
  5205. procedure TEditor.Update_Place_Markers (AddCount : Word; KillCount : Word;
  5206.                                         StartPtr : Word;    EndPtr : Word);
  5207.  
  5208.  
  5209.   { -------------------------------------------------------- }
  5210.   {                                                          }
  5211.   { This procedure updates the position of the place markers }
  5212.   { as the user inserts and deletes text in the document.    }
  5213.   {                                                          }
  5214.   { -------------------------------------------------------- }
  5215.  
  5216.  
  5217. VAR
  5218.  
  5219.   Element : Byte;     { Place_Marker array element to traverse array with. }
  5220.  
  5221.  
  5222. begin
  5223.  
  5224.   for Element := 1 to 10 do
  5225.     begin
  5226.       if AddCount > 0 then
  5227.         begin
  5228.           if (Place_Marker[Element] >= Curptr)
  5229.               and (Place_Marker[Element] <> 0) then
  5230.             Place_Marker[Element] := Place_Marker[Element] + AddCount;
  5231.         end
  5232.       else
  5233.         begin
  5234.           if Place_Marker[Element] >= StartPtr then
  5235.             begin
  5236.               if (Place_Marker[Element] >= StartPtr) and
  5237.                  (Place_Marker[Element] < EndPtr) then
  5238.                 Place_marker[Element] := 0
  5239.               else
  5240.                 begin
  5241.                   if integer (Place_Marker[Element]) - integer (KillCount) > 0 then
  5242.                     Place_Marker[Element] := Place_Marker[Element] - KillCount
  5243.                   else
  5244.                     Place_Marker[Element] := 0;
  5245.                 end;
  5246.             end;
  5247.         end;
  5248.     end;
  5249.  
  5250.   { WRAP - Start. }
  5251.  
  5252.   if AddCount > 0 then
  5253.     BlankLine := BlankLine + AddCount
  5254.   else
  5255.     begin
  5256.       if integer (BlankLine) - Integer (KillCount) > 0 then
  5257.         BlankLine := BlankLine - KillCount
  5258.       else
  5259.         BlankLine := 0;
  5260.     end;
  5261.  
  5262.   { WRAP - Stop. }
  5263.  
  5264.  
  5265. end; { TEditor.Update_Place_Markers }
  5266.  
  5267. {MARK - Stop. }
  5268.  
  5269.  
  5270.  
  5271. { -------------------------------------------------------------------------- }
  5272.  
  5273.  
  5274.  
  5275. function TEditor.Valid (Command : Word) : Boolean;
  5276.  
  5277. begin
  5278.  
  5279.   Valid := IsValid;
  5280.  
  5281.  
  5282. end; { TEditor.Valid }
  5283.  
  5284.  
  5285.  
  5286. { -------------------------------------------------------------------------- }
  5287.  
  5288.  
  5289.  
  5290.          { ----------------------------------------------- }
  5291.          {                                                 }
  5292.          { The following methods are for the TMEMO object. }
  5293.          {                                                 }
  5294.          { ----------------------------------------------- }
  5295.  
  5296.  
  5297.  
  5298. constructor TMemo.Load (var S : Objects.TStream);
  5299.  
  5300. VAR
  5301.  
  5302.   Length : Word;
  5303.  
  5304. begin
  5305.  
  5306.   TEditor.Load (S);
  5307.   S.Read (Length, SizeOf (Word));
  5308.  
  5309.   if IsValid then
  5310.     begin
  5311.       S.Read (Buffer^[BufSize - Length], Length);
  5312.       SetBufLen (Length);
  5313.     end
  5314.   else
  5315.     S.Seek (S.GetPos + Length);
  5316.  
  5317.  
  5318. end; { TMemo.Load }
  5319.  
  5320.  
  5321.  
  5322. { -------------------------------------------------------------------------- }
  5323.  
  5324.  
  5325.  
  5326. function TMemo.DataSize : Word;
  5327.  
  5328. begin
  5329.  
  5330.   DataSize := BufSize + SizeOf (Word);
  5331.  
  5332.  
  5333. end; { TMemo.DataSize }
  5334.  
  5335.  
  5336.  
  5337. { -------------------------------------------------------------------------- }
  5338.  
  5339.  
  5340.  
  5341. procedure TMemo.GetData (var Rec);
  5342.  
  5343. VAR
  5344.  
  5345.   Data : TMemoData absolute Rec;
  5346.  
  5347. begin
  5348.  
  5349.   Data.Length := BufLen;
  5350.   Move (Buffer^, Data.Buffer, CurPtr);
  5351.   Move (Buffer^[CurPtr + GapLen], Data.Buffer[CurPtr], BufLen - CurPtr);
  5352.   FillChar (Data.Buffer[BufLen], BufSize - BufLen, 0);
  5353.  
  5354.  
  5355. end; { TMemo.GetData }
  5356.  
  5357.  
  5358.  
  5359. { -------------------------------------------------------------------------- }
  5360.  
  5361.  
  5362.  
  5363. function TMemo.GetPalette : Views.PPalette;
  5364.  
  5365. CONST
  5366.  
  5367.   P : String[Length (CMemo)] = CMemo;
  5368.  
  5369. begin
  5370.  
  5371.   GetPalette := @P;
  5372.  
  5373.  
  5374. end; { TMemo.GetPalette }
  5375.  
  5376.  
  5377.  
  5378. { -------------------------------------------------------------------------- }
  5379.  
  5380.  
  5381.  
  5382. procedure TMemo.HandleEvent (var Event : Drivers.TEvent);
  5383.  
  5384. begin
  5385.  
  5386.   if (Event.What <> Drivers.evKeyDown) or (Event.KeyCode <> Drivers.kbTab) then
  5387.     TEditor.HandleEvent (Event);
  5388.  
  5389.  
  5390. end; { TMemo.HandleEvent }
  5391.  
  5392.  
  5393.  
  5394. { -------------------------------------------------------------------------- }
  5395.  
  5396.  
  5397.  
  5398. procedure TMemo.SetData (var Rec);
  5399.  
  5400. VAR
  5401.  
  5402.   Data : TMemoData absolute Rec;
  5403.  
  5404. begin
  5405.  
  5406.   Move (Data.Buffer, Buffer^[BufSize - Data.Length], Data.Length);
  5407.   SetBufLen (Data.Length);
  5408.  
  5409.  
  5410. end; { TMemo.SetData }
  5411.  
  5412.  
  5413.  
  5414. { -------------------------------------------------------------------------- }
  5415.  
  5416.  
  5417.  
  5418. procedure TMemo.Store (var S : Objects.TStream);
  5419.  
  5420. begin
  5421.  
  5422.   TEditor.Store (S);
  5423.   S.Write (BufLen, SizeOf (Word));
  5424.   S.Write (Buffer^, CurPtr);
  5425.   S.Write (Buffer^[CurPtr + GapLen], BufLen - CurPtr);
  5426.  
  5427.  
  5428. end; { TMemo.Store }
  5429.  
  5430.  
  5431.  
  5432. { -------------------------------------------------------------------------- }
  5433.  
  5434.  
  5435.  
  5436.          { ----------------------------------------------------- }
  5437.          {                                                       }
  5438.          { The following methods are for the TFILEEDITOR object. }
  5439.          {                                                       }
  5440.          { ----------------------------------------------------- }
  5441.  
  5442.  
  5443.  
  5444. constructor TFileEditor.Init (var Bounds : TRect;
  5445.                               AHScrollBar, AVScrollBar : PScrollBar;
  5446.                               AIndicator : PIndicator;
  5447.                               AFileName  : FNameStr);
  5448.  
  5449. begin
  5450.  
  5451.   TEditor.Init (Bounds, AHScrollBar, AVScrollBar, AIndicator, 0);
  5452.  
  5453.   if AFileName <> '' then
  5454.   begin
  5455.  
  5456.     FileName := FExpand (AFileName);
  5457.     if IsValid then
  5458.       IsValid := LoadFile;
  5459.  
  5460.   end;
  5461.  
  5462.  
  5463. end; { TFileEditor.Init }
  5464.  
  5465.  
  5466.  
  5467. { -------------------------------------------------------------------------- }
  5468.  
  5469.  
  5470.  
  5471. constructor TFileEditor.Load (var S : Objects.TStream);
  5472.  
  5473. VAR
  5474.  
  5475.   SStart : Word;
  5476.   SEnd   : Word;
  5477.   Curs   : Word;
  5478.  
  5479. begin
  5480.  
  5481.   TEditor.Load (S);
  5482.  
  5483.   S.Read (FileName[0], SizeOf (Char));
  5484.   S.Read (Filename[1], Length (FileName));
  5485.  
  5486.   if IsValid then
  5487.     IsValid := LoadFile;
  5488.  
  5489.   S.Read (SStart, SizeOf (Word));
  5490.   S.Read (SEnd, SizeOf (Word));
  5491.   S.Read (Curs, SizeOf (Word));
  5492.  
  5493.   if IsValid and (SEnd <= BufLen) then
  5494.   begin
  5495.     SetSelect (SStart, SEnd, Curs = SStart);
  5496.     TrackCursor (True);
  5497.   end;
  5498.  
  5499.  
  5500. end; { TFileEditor.Load }
  5501.  
  5502.  
  5503.  
  5504. { -------------------------------------------------------------------------- }
  5505.  
  5506.  
  5507.  
  5508. procedure TFileEditor.DoneBuffer;
  5509.  
  5510. begin
  5511.  
  5512.   if Buffer <> nil then
  5513.     DisposeBuffer (Buffer);
  5514.  
  5515.  
  5516. end; { TFileEditor.DoneBuffer }
  5517.  
  5518.  
  5519.  
  5520. { -------------------------------------------------------------------------- }
  5521.  
  5522.  
  5523.  
  5524. procedure TFileEditor.HandleEvent (var Event : Drivers.TEvent);
  5525.  
  5526. begin
  5527.  
  5528.   TEditor.HandleEvent (Event);
  5529.  
  5530.   case Event.What of
  5531.     Drivers.evCommand:
  5532.       case Event.Command of
  5533.  
  5534.         cmSave   : Save;
  5535.         cmSaveAs : SaveAs;
  5536.  
  5537.         { SAVE - Start. }
  5538.  
  5539.         cmSaveDone : if Save then
  5540.                        Message (Owner, Drivers.evCommand, Views.cmClose, nil);
  5541.  
  5542.         { SAVE - Stop. } { Added code to remove editor if ^KD or ^KX pressed. }
  5543.  
  5544.       else
  5545.         Exit;
  5546.       end;
  5547.   else
  5548.     Exit;
  5549.   end;
  5550.  
  5551.   ClearEvent (Event);
  5552.  
  5553.  
  5554. end; { TFileEditor.HandleEvent }
  5555.  
  5556.  
  5557.  
  5558. { -------------------------------------------------------------------------- }
  5559.  
  5560.  
  5561.  
  5562. procedure TFileEditor.InitBuffer;
  5563.  
  5564. begin
  5565.  
  5566.   NewBuffer (Pointer (Buffer));
  5567.  
  5568.   { LOAD  - Start. }
  5569.   { STORE - Start. }
  5570.  
  5571.   BufSize := 0;
  5572.  
  5573.   { STORE - Stop. }
  5574.   { LOAD  - Stop. }
  5575.  
  5576.  
  5577. end; { TFileEditor.InitBuffer }
  5578.  
  5579.  
  5580.  
  5581. { -------------------------------------------------------------------------- }
  5582.  
  5583.  
  5584.  
  5585. function TFileEditor.LoadFile : Boolean;
  5586.  
  5587. VAR
  5588.  
  5589.   Length : Word;
  5590.   FSize  : Longint;
  5591.   F      : File;
  5592.  
  5593. begin
  5594.  
  5595.   LoadFile := False;
  5596.   Length := 0;
  5597.   Assign (F, FileName);
  5598.   Reset (F, 1);
  5599.  
  5600.   if IOResult <> 0 then
  5601.     LoadFile := True
  5602.   else
  5603.     begin
  5604.  
  5605.       FSize := FileSize (F);
  5606.  
  5607.       if (FSize > $FFF0) or not SetBufSize (Word (FSize)) then
  5608.         EditorDialog (edOutOfMemory, nil)
  5609.       else
  5610.         begin
  5611.  
  5612.           BlockRead (F, Buffer^[BufSize - Word (FSize)], FSize);
  5613.  
  5614.           if IOResult <> 0 then
  5615.             EditorDialog (edReadError, @FileName)
  5616.           else
  5617.             begin
  5618.               LoadFile := True;
  5619.               Length := FSize;
  5620.             end;
  5621.  
  5622.         end;
  5623.  
  5624.         Close (F);
  5625.  
  5626.     end;
  5627.  
  5628.   SetBufLen (Length);
  5629.  
  5630.  
  5631. end; { TFileEditor.LoadFile }
  5632.  
  5633.  
  5634.  
  5635. { -------------------------------------------------------------------------- }
  5636.  
  5637.  
  5638.  
  5639. function TFileEditor.Save : Boolean;
  5640.  
  5641. begin
  5642.  
  5643.   if FileName = '' then
  5644.     Save := SaveAs
  5645.   else
  5646.     Save := SaveFile;
  5647.  
  5648.  
  5649. end; { TFileEditor.Save }
  5650.  
  5651.  
  5652.  
  5653. { -------------------------------------------------------------------------- }
  5654.  
  5655.  
  5656.  
  5657. function TFileEditor.SaveAs : Boolean;
  5658.  
  5659. begin
  5660.  
  5661.   SaveAs := False;
  5662.  
  5663.   if EditorDialog (edSaveAs, @FileName) <> Views.cmCancel then
  5664.   begin
  5665.  
  5666.     FileName := FExpand (FileName);
  5667.     Message (Owner, Drivers.evBroadcast, cmUpdateTitle, nil);
  5668.     SaveAs := SaveFile;
  5669.  
  5670.     if IsClipboard then
  5671.       FileName := '';
  5672.   end;
  5673.  
  5674.  
  5675. end; { TFileEditor.SaveAs }
  5676.  
  5677.  
  5678.  
  5679. { -------------------------------------------------------------------------- }
  5680.  
  5681.  
  5682.  
  5683. function TFileEditor.SaveFile : Boolean;
  5684.  
  5685. VAR
  5686.  
  5687.   F          : File;
  5688.   BackupName : Objects.FNameStr;
  5689.   D          : DOS.DirStr;
  5690.   N          : DOS.NameStr;
  5691.   E          : DOS.ExtStr;
  5692.  
  5693. begin
  5694.  
  5695.   SaveFile := False;
  5696.  
  5697.   if EditorFlags and efBackupFiles <> 0 then
  5698.   begin
  5699.     FSplit (FileName, D, N, E);
  5700.     BackupName := D + N + '.BAK';
  5701.     Assign (F, BackupName);
  5702.     Erase (F);
  5703.     Assign (F, FileName);
  5704.     Rename (F, BackupName);
  5705.     InOutRes := 0;
  5706.   end;
  5707.  
  5708.   Assign (F, FileName);
  5709.   Rewrite (F, 1);
  5710.  
  5711.   if IOResult <> 0 then
  5712.     EditorDialog (edCreateError, @FileName)
  5713.   else
  5714.     begin
  5715.  
  5716.       BlockWrite (F, Buffer^, CurPtr);
  5717.       BlockWrite (F, Buffer^[CurPtr + GapLen], BufLen - CurPtr);
  5718.  
  5719.       if IOResult <> 0 then
  5720.         EditorDialog (edWriteError, @FileName)
  5721.       else
  5722.         begin
  5723.           Modified := False;
  5724.           Update (ufUpdate);
  5725.           SaveFile := True;
  5726.         end;
  5727.         Close (F);
  5728.       end;
  5729.  
  5730.  
  5731. end; { TFileEditor.SaveFile }
  5732.  
  5733.  
  5734.  
  5735. { -------------------------------------------------------------------------- }
  5736.  
  5737.  
  5738.  
  5739. function TFileEditor.SetBufSize (NewSize : Word) : Boolean;
  5740.  
  5741. VAR
  5742.  
  5743.   N : Word;
  5744.  
  5745. begin
  5746.  
  5747.   SetBufSize := False;
  5748.   if NewSize > $F000 then
  5749.     NewSize := $FFF0
  5750.   else
  5751.     NewSize := (NewSize + $0FFF) and $F000;
  5752.  
  5753.   if NewSize <> BufSize then
  5754.   begin
  5755.  
  5756.     if NewSize > BufSize then
  5757.       if not SetBufferSize (Buffer, NewSize) then
  5758.         Exit;
  5759.  
  5760.     N := BufLen - CurPtr + DelCount;
  5761.     Move (Buffer^[BufSize - N], Buffer^[NewSize - N], N);
  5762.  
  5763.     if NewSize < BufSize then
  5764.       SetBufferSize (Buffer, NewSize);
  5765.  
  5766.     BufSize := NewSize;
  5767.     GapLen := BufSize - BufLen;
  5768.  
  5769.   end;
  5770.  
  5771.   SetBufSize := True;
  5772.  
  5773.  
  5774. end; { TFileEditor.SetBufSize }
  5775.  
  5776.  
  5777.  
  5778. { -------------------------------------------------------------------------- }
  5779.  
  5780.  
  5781.  
  5782. procedure TFileEditor.Store (var S : Objects.TStream);
  5783.  
  5784. begin
  5785.  
  5786.   TEditor.Store (S);
  5787.   S.Write (FileName, Length (FileName) + 1);
  5788.   S.Write (SelStart, SizeOf (Word) * 3);
  5789.  
  5790.  
  5791. end; { TFileEditor.Store }
  5792.  
  5793.  
  5794.  
  5795. { -------------------------------------------------------------------------- }
  5796.  
  5797.  
  5798.  
  5799. procedure TFileEditor.UpdateCommands;
  5800.  
  5801. begin
  5802.  
  5803.   TEditor.UpdateCommands;
  5804.  
  5805.   SetCmdState (cmSave, True);
  5806.   SetCmdState (cmSaveAs, True);
  5807.  
  5808.   { SAVE - Start. }
  5809.  
  5810.   SetCmdState (cmSaveDone, True);
  5811.  
  5812.   { SAVE - Stop. } { Added cmSaveDone toggle. }
  5813.  
  5814.  
  5815.  
  5816.   { -------------------------------------------------------------------- }
  5817.   {                                                                      }
  5818.   { The following SetCmdState calls are included to allow you to disable }
  5819.   { any custom menu options you design for the editor features.  I have  }
  5820.   { commented them out.  You pay a price in speed performance for EACH   }
  5821.   { option you uncomment.  Read the MENU section of NEWEDIT.DOC!         }
  5822.   {                                                                      }
  5823.   { -------------------------------------------------------------------- }
  5824.  
  5825.  
  5826.   { CENTER - Start. }
  5827.   { HOMEND - Start. }
  5828.   { INSLIN - Start. }
  5829.   { JLINE  - Start. }
  5830.   { MARK   - Start. }
  5831.   { PRETAB - Start. }
  5832.   { REFDOC - Start. }
  5833.   { REFORM - Start. }
  5834.   { RMSET  - Start. }
  5835.   { SCRLDN - Start. }
  5836.   { SCRLDN - Start. }
  5837.   { SELWRD - Start. }
  5838.   { WRAP   - Start. }
  5839.  
  5840.   { SetCmdState (cmCenterText, True);  }
  5841.   { SetCmdState (cmEndPage, True);     }
  5842.   { SetCmdState (cmHomePage, True);    }
  5843.   { SetCmdState (cmIndentMode, True);  }
  5844.   { SetCmdState (cmInsertLine, True);  }
  5845.   { SetCmdState (cmJumpLine, True);    }
  5846.   { SetCmdState (cmJumpMark0, True);   }
  5847.   { SetCmdState (cmJumpMark1, True);   }
  5848.   { SetCmdState (cmJumpMark2, True);   }
  5849.   { SetCmdState (cmJumpMark3, True);   }
  5850.   { SetCmdState (cmJumpMark4, True);   }
  5851.   { SetCmdState (cmJumpMark5, True);   }
  5852.   { SetCmdState (cmJumpMark6, True);   }
  5853.   { SetCmdState (cmJumpMark7, True);   }
  5854.   { SetCmdState (cmJumpMark8, True);   }
  5855.   { SetCmdState (cmJumpMark9, True);   }
  5856.   { SetCmdState (cmReformDoc, True);   }
  5857.   { SetCmdState (cmReformPara, True);  }
  5858.   { SetCmdState (cmRightMargin, True); }
  5859.   { SetCmdState (cmScrollDown, True);  }
  5860.   { SetCmdState (cmScrollUp, True);    }
  5861.   { SetCmdState (cmSelectWord, True);  }
  5862.   { SetCmdState (cmSetMark0, True);    }
  5863.   { SetCmdState (cmSetMark1, True);    }
  5864.   { SetCmdState (cmSetMark2, True);    }
  5865.   { SetCmdState (cmSetMark3, True);    }
  5866.   { SetCmdState (cmSetMark4, True);    }
  5867.   { SetCmdState (cmSetMark5, True);    }
  5868.   { SetCmdState (cmSetMark6, True);    }
  5869.   { SetCmdState (cmSetMark7, True);    }
  5870.   { SetCmdState (cmSetMark8, True);    }
  5871.   { SetCmdState (cmSetMark9, True);    }
  5872.   { SetCmdState (cmSetTabs, True);     }
  5873.   { SetCmdState (cmTabKey, True);      }
  5874.   { SetCmdState (cmWordWrap, True);    }
  5875.  
  5876.  
  5877.   { WRAP   - Stop. }
  5878.   { SELWRD - Stop. }
  5879.   { SCRLUP - Stop. }
  5880.   { SCRLDN - Stop. }
  5881.   { RMSET  - Stop. }
  5882.   { REFORM - Stop. }
  5883.   { REFDOC - Stop. }
  5884.   { PRETAB - Stop. }
  5885.   { MARK   - Stop. }
  5886.   { JLINE  - Stop. }
  5887.   { INSLIN - Stop. }
  5888.   { HOMEND - Stop. }
  5889.   { CENTER - Stop. } { This was required so these command constants may }
  5890.                      { be used in enabling and disabling menu options.  }
  5891.  
  5892.  
  5893. end; { TFileEditor.UpdateCommands }
  5894.  
  5895.  
  5896.  
  5897. { -------------------------------------------------------------------------- }
  5898.  
  5899.  
  5900.  
  5901. function TFileEditor.Valid (Command : Word) : Boolean;
  5902.  
  5903. VAR
  5904.  
  5905.   D : Integer;
  5906.  
  5907. begin
  5908.  
  5909.   if Command = Views.cmValid then
  5910.     Valid := IsValid
  5911.   else
  5912.     begin
  5913.  
  5914.       Valid := True;
  5915.  
  5916.       if Modified then
  5917.       begin
  5918.  
  5919.         if FileName = '' then
  5920.           D := edSaveUntitled
  5921.         else
  5922.           D := edSaveModify;
  5923.  
  5924.         case EditorDialog (D, @FileName) of
  5925.           Views.cmYes    : Valid := Save;
  5926.           Views.cmNo     : Modified := False;
  5927.           Views.cmCancel : Valid := False;
  5928.  
  5929.         end;
  5930.  
  5931.       end;
  5932.  
  5933.     end;
  5934.  
  5935.  
  5936. end; { TFileEditor.Valid }
  5937.  
  5938.  
  5939.  
  5940. { -------------------------------------------------------------------------- }
  5941.  
  5942.  
  5943.  
  5944.          { ----------------------------------------------------- }
  5945.          {                                                       }
  5946.          { The following methods are for the TEDITWINDOW object. }
  5947.          {                                                       }
  5948.          { ----------------------------------------------------- }
  5949.  
  5950.  
  5951.  
  5952. constructor TEditWindow.Init (var Bounds   : TRect;
  5953.                                   FileName : Objects.FNameStr;
  5954.                                   ANumber  : Integer);
  5955.  
  5956. VAR
  5957.  
  5958.   HScrollBar : Views.PScrollBar;
  5959.   VScrollBar : Views.PScrollBar;
  5960.   Indicator  : PIndicator;
  5961.   R          : TRect;
  5962.  
  5963. begin
  5964.  
  5965.   TWindow.Init (Bounds, '', ANumber);
  5966.   Options := Options or Views.ofTileable;
  5967.  
  5968.   R.Assign (18, Size.Y - 1, Size.X - 2, Size.Y);
  5969.   HScrollBar := New (Views.PScrollBar, Init (R));
  5970.   HScrollBar^.Hide;
  5971.   Insert (HScrollBar);
  5972.  
  5973.   R.Assign (Size.X - 1, 1, Size.X, Size.Y - 1);
  5974.   VScrollBar := New (Views.PScrollBar, Init (R));
  5975.   VScrollBar^.Hide;
  5976.   Insert (VScrollBar);
  5977.  
  5978.   R.Assign (2, Size.Y - 1, 16, Size.Y);
  5979.   Indicator := New (PIndicator, Init (R));
  5980.   Indicator^.Hide;
  5981.   Insert (Indicator);
  5982.  
  5983.   GetExtent (R);
  5984.   R.Grow (-1, -1);
  5985.   Editor := New (PFileEditor, Init (R, HScrollBar, VScrollBar, Indicator, FileName));
  5986.  
  5987.   Insert (Editor);
  5988.  
  5989.  
  5990. end; { TEditWindow.Init }
  5991.  
  5992.  
  5993.  
  5994. { -------------------------------------------------------------------------- }
  5995.  
  5996.  
  5997.  
  5998. constructor TEditWindow.Load (var S : Objects.TStream);
  5999.  
  6000. begin
  6001.  
  6002.   TWindow.Load (S);
  6003.   GetSubViewPtr (S, Editor);
  6004.  
  6005.  
  6006. end; { TEditWindow.Load }
  6007.  
  6008.  
  6009.  
  6010. { -------------------------------------------------------------------------- }
  6011.  
  6012.  
  6013.  
  6014. procedure TEditWindow.Close;
  6015.  
  6016. VAR
  6017.  
  6018.   Event : Drivers.TEvent;
  6019.  
  6020. begin
  6021.  
  6022.   if Editor^.IsClipboard then
  6023.     Hide
  6024.   else
  6025.     TWindow.Close;
  6026.  
  6027.  
  6028. end; { TEditWindow.Close }
  6029.  
  6030.  
  6031.  
  6032. { -------------------------------------------------------------------------- }
  6033.  
  6034.  
  6035.  
  6036. function TEditWindow.GetTitle (MaxSize : Integer) : Views.TTitleStr;
  6037.  
  6038. begin
  6039.  
  6040.   if Editor^.IsClipboard then
  6041.     GetTitle := 'Clipboard'
  6042.   else
  6043.     if Editor^.FileName = '' then
  6044.       GetTitle := 'Untitled'
  6045.     else
  6046.       GetTitle := Editor^.FileName;
  6047.  
  6048.  
  6049. end; { TEditWindow.GetTile }
  6050.  
  6051.  
  6052.  
  6053. { -------------------------------------------------------------------------- }
  6054.  
  6055.  
  6056.  
  6057. procedure TEditWindow.HandleEvent (var Event : Drivers.TEvent);
  6058.  
  6059. begin
  6060.  
  6061.   TWindow.HandleEvent (Event);
  6062.  
  6063.   if (Event.What = Drivers.evBroadcast) then
  6064.     { and (Event.Command = cmUpdateTitle) then }
  6065.  
  6066.  
  6067.  
  6068.     { STATS - Start. }
  6069.  
  6070.     { -------------------------------------------------------------------- }
  6071.     {                                                                      }
  6072.     { Changed if statement above so I could test for cmBlugeonStats.       }
  6073.     { Stats would not show up when loading a file until a key was pressed. }
  6074.     {                                                                      }
  6075.     { -------------------------------------------------------------------- }
  6076.  
  6077.  
  6078.     case Event.Command of
  6079.       cmUpdateTitle   : begin
  6080.                           Frame^.DrawView;
  6081.                           ClearEvent (Event);
  6082.                         end;
  6083.  
  6084.       cmBludgeonStats : begin
  6085.                           Editor^.Update (ufStats);
  6086.                           ClearEvent (Event);
  6087.                         end;
  6088.     end;
  6089.  
  6090.     { STATS - Stop. }
  6091.  
  6092.  
  6093. end; { TEditWindow.HandleEvent }
  6094.  
  6095.  
  6096.  
  6097. { -------------------------------------------------------------------------- }
  6098.  
  6099.  
  6100.  
  6101. procedure TEditWindow.Store (var S : Objects.TStream);
  6102.  
  6103. begin
  6104.  
  6105.   TWindow.Store (S);
  6106.   PutSubViewPtr (S, Editor);
  6107.  
  6108.  
  6109. end; { TEditWindow.Store }
  6110.  
  6111.  
  6112.  
  6113. { -------------------------------------------------------------------------- }
  6114.  
  6115.  
  6116.  
  6117. procedure RegisterEditors;
  6118.  
  6119. begin
  6120.  
  6121.   RegisterType (REditor);
  6122.   RegisterType (RMemo);
  6123.   RegisterType (RFileEditor);
  6124.   RegisterType (RIndicator);
  6125.   RegisterType (REditWindow);
  6126.  
  6127. end; { RegisterEditors }
  6128.  
  6129.  
  6130.  
  6131. { -------------------------------------------------------------------------- }
  6132.  
  6133.  
  6134.  
  6135. end. { Unit NewEdit }
  6136.